Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Futures

Overview
Creating asynchronous values
Wait Callbacks and Lazy Futures
Handling Detached Threads and Thread Specific Variables
Executing asynchronously
Shared Futures
Making immediate futures easier
Associating future continuations
Futures Reference
Enumeration state
Enumeration future_errc
Enumeration launch
Specialization is_error_code_enum<future_errc>
Non-member function make_error_code()
Non-member function make_error_condition()
Non-member function future_category()
Class future_error
Enumeration future_status
Class exceptional_ptr EXPERIMENTAL
future class template
shared_future class template
promise class template
packaged_task class template
Non-member function decay_copy()
Non-member function async()
Non-member function wait_for_any() - EXTENSION
Non-member function wait_for_all() - EXTENSION
Non-member function when_all() - EXTENSION
Non-member function when_any() - EXTENSION
Non-member function make_ready_future() EXTENSION
Non-member function make_exceptional() EXTENSION
Non-member function make_future() DEPRECATED
Non-member function make_shared_future() DEPRECATED

The futures library provides a means of handling synchronous future values, whether those values are generated by another thread, or on a single thread in response to external stimuli, or on-demand.

This is done through the provision of four class templates: future and boost::shared_future which are used to retrieve the asynchronous results, and boost::promise and boost::packaged_task which are used to generate the asynchronous results.

An instance of future holds the one and only reference to a result. Ownership can be transferred between instances using the move constructor or move-assignment operator, but at most one instance holds a reference to a given asynchronous result. When the result is ready, it is returned from boost::future<R>::get() by rvalue-reference to allow the result to be moved or copied as appropriate for the type.

On the other hand, many instances of boost::shared_future may reference the same result. Instances can be freely copied and assigned, and boost::shared_future<R>::get() returns a const reference so that multiple calls to boost::shared_future<R>::get() are safe. You can move an instance of future into an instance of boost::shared_future, thus transferring ownership of the associated asynchronous result, but not vice-versa.

boost::async is a simple way of running asynchronous tasks. A call to boost::async returns a future that will contain the result of the task.

You can wait for futures either individually or with one of the boost::wait_for_any() and boost::wait_for_all() functions.

You can set the value in a future with either a boost::promise or a boost::packaged_task. A boost::packaged_task is a callable object that wraps a function or callable object. When the packaged task is invoked, it invokes the contained function in turn, and populates a future with the return value. This is an answer to the perennial question: "how do I return a value from a thread?": package the function you wish to run as a boost::packaged_task and pass the packaged task to the thread constructor. The future retrieved from the packaged task can then be used to obtain the return value. If the function throws an exception, that is stored in the future in place of the return value.

int calculate_the_answer_to_life_the_universe_and_everything()
{
    return 42;
}

boost::packaged_task<int> pt(calculate_the_answer_to_life_the_universe_and_everything);
boost:: future<int> fi=pt.get_future();

boost::thread task(boost::move(pt)); // launch task on a thread

fi.wait(); // wait for it to finish

assert(fi.is_ready());
assert(fi.has_value());
assert(!fi.has_exception());
assert(fi.get_state()==boost::future_state::ready);
assert(fi.get()==42);

A boost::promise is a bit more low level: it just provides explicit functions to store a value or an exception in the associated future. A promise can therefore be used where the value may come from more than one possible source, or where a single operation may produce multiple values.

boost::promise<int> pi;
boost:: future<int> fi;
fi=pi.get_future();

pi.set_value(42);

assert(fi.is_ready());
assert(fi.has_value());
assert(!fi.has_exception());
assert(fi.get_state()==boost::future_state::ready);
assert(fi.get()==42);

Both boost::promise and boost::packaged_task support wait callbacks that are invoked when a thread blocks in a call to wait() or timed_wait() on a future that is waiting for the result from the boost::promise or boost::packaged_task, in the thread that is doing the waiting. These can be set using the set_wait_callback() member function on the boost::promise or boost::packaged_task in question.

This allows lazy futures where the result is not actually computed until it is needed by some thread. In the example below, the call to f.get() invokes the callback invoke_lazy_task, which runs the task to set the value. If you remove the call to f.get(), the task is not ever run.

int calculate_the_answer_to_life_the_universe_and_everything()
{
    return 42;
}

void invoke_lazy_task(boost::packaged_task<int>& task)
{
    try
    {
        task();
    }
    catch(boost::task_already_started&)
    {}
}

int main()
{
    boost::packaged_task<int> task(calculate_the_answer_to_life_the_universe_and_everything);
    task.set_wait_callback(invoke_lazy_task);
    boost:: future<int> f(task.get_future());

    assert(f.get()==42);
}

Detached threads pose a problem for objects with thread storage duration. If we use a mechanism other than thread::__join to wait for a thread to complete its work - such as waiting for a future to be ready - then the destructors of thread specific variables will still be running after the waiting thread has resumed. This section explain how the standard mechanism can be used to make such synchronization safe by ensuring that the objects with thread storage duration are destroyed prior to the future being made ready. e.g.

int find_the_answer(); // uses thread specific objects
void thread_func(boost::promise<int>&& p)
{
    p.set_value_at_thread_exit(find_the_answer());
}

int main()
{
    boost::promise<int> p;
    boost::thread t(thread_func,boost::move(p));
    t.detach(); // we're going to wait on the future
    std::cout<<p.get_future().get()<<std::endl;
}

When the call to get() returns, we know that not only is the future value ready, but the thread specific variables on the other thread have also been destroyed.

Such mechanisms are provided for boost::condition_variable, boost::promise and boost::packaged_task. e.g.

void task_executor(boost::packaged_task<void(int)> task,int param)
{
    task.make_ready_at_thread_exit(param); // execute stored task
} // destroy thread specific and wake threads waiting on futures from task

Other threads can wait on a future obtained from the task without having to worry about races due to the execution of destructors of the thread specific objects from the task's thread.

boost::condition_variable cv;
boost::mutex m;
complex_type the_data;
bool data_ready;

void thread_func()
{
    boost::unique_lock<std::mutex> lk(m);
    the_data=find_the_answer();
    data_ready=true;
    boost::notify_all_at_thread_exit(cv,boost::move(lk));
} // destroy thread specific objects, notify cv, unlock mutex

void waiting_thread()
{
    boost::unique_lock<std::mutex> lk(m);
    while(!data_ready)
    {
        cv.wait(lk);
    }
    process(the_data);
}

The waiting thread is guaranteed that the thread specific objects used by thread_func() have been destroyed by the time process(the_data) is called. If the lock on m is released and re-acquired after setting data_ready and before calling boost::notify_all_at_thread_exit() then this does NOT hold, since the thread may return from the wait due to a spurious wake-up.

boost::async is a simple way of running asynchronous tasks to make use of the available hardware concurrency. A call to boost::async returns a boost::future that will contain the result of the task. Depending on the launch policy, the task is either run asynchronously on its own thread or synchronously on whichever thread calls the wait() or get() member functions on that future.

A launch policy of either boost::launch::async, which asks the runtime to create an asynchronous thread, or boost::launch::deferred, which indicates you simply want to defer the function call until a later time (lazy evaluation). This argument is optional - if you omit it your function will use the default policy.

For example, consider computing the sum of a very large array. The first task is to not compute asynchronously when the overhead would be significant. The second task is to split the work into two pieces, one executed by the host thread and one executed asynchronously.

int parallel_sum(int* data, int size)
{
  int sum = 0;
  if ( size < 1000 )
    for ( int i = 0; i < size; ++i )
      sum += data[i];
  else {
    auto handle = boost::async(parallel_sum, data+size/2, size-size/2);
    sum += parallel_sum(data, size/2);
    sum += handle.get();
  }
  return sum;
}

shared_future is designed to be shared between threads, that is to allow multiple concurrent get operations.

Multiple get

The second get() call in the following example is undefined.

void bad_second_use( type arg ) {

  auto ftr = async( [=]{ return work( arg ); } );
    if ( cond1 )
    {
        use1( ftr.get() );
    } else
    {
        use2( ftr.get() );
    }
    use3( ftr.get() ); // second use is undefined
}

Using a shared_future solves the issue

void good_second_use( type arg ) {

   shared_future<type> ftr = async( [=]{ return work( arg ); } );
    if ( cond1 )
    {
        use1( ftr.get() );
    } else
    {
        use2(  ftr.get() );
    }
    use3( ftr.get() ); // second use is defined
}
share()

Naming the return type when declaring the shared_future is needed; auto is not available within template argument lists. Here share() could be used to simplify the code

void better_second_use( type arg ) {

   auto ftr = async( [=]{ return work( arg ); } ).share();
    if ( cond1 )
    {
        use1( ftr.get() );
    } else
    {
        use2(  ftr.get() );
    }
    use3( ftr.get() ); // second use is defined
}
Writing on get()

The user can either read or write the future variable.

void write_to_get( type arg ) {

   auto ftr = async( [=]{ return work( arg ); } ).share();
    if ( cond1 )
    {
        use1( ftr.get() );
    } else
    {
      if ( cond2 )
        use2(  ftr.get() );
      else
        ftr.get() = something(); // assign to non-const reference.  
    }
    use3( ftr.get() ); // second use is defined
}

This works because the shared_future<>::get() function returns a non-const reference to the appropriate storage. Of course the access to this storage must be ensured by the user. The library doesn't ensure the access to the internal storage is thread safe.

There has been some work by the C++ standard committee on an atomic_future that behaves as an atomic variable, that is thread_safe, and a shared_future that can be shared between several threads, but there were not enough consensus and time to get it ready for C++11.

Some functions may know the value at the point of construction. In these cases the value is immediately available, but needs to be returned as a future or shared_future. By using make_ready_future a future can be created which holds a pre-computed result in its shared state.

Without these features it is non-trivial to create a future directly from a value. First a promise must be created, then the promise is set, and lastly the future is retrieved from the promise. This can now be done with one operation.

make_ready_future

This function creates a future for a given value. If no value is given then a future<void> is returned. This function is primarily useful in cases where sometimes, the return value is immediately available, but sometimes it is not. The example below illustrates, that in an error path the value is known immediately, however in other paths the function must return an eventual value represented as a future.

boost::future<int> compute(int x)
{
  if (x == 0) return boost::make_ready_future(0);
  if (x < 0) return boost::make_ready_future<int>(std::logic_error("Error"));
  boost::future<int> f1 = boost::async([]() { return x+1; });
  return f1;
}

There are two variations of this function. The first takes a value of any type, and returns a future of that type. The input value is passed to the shared state of the returned future. The second version takes no input and returns a future<void>.

In asynchronous programming, it is very common for one asynchronous operation, on completion, to invoke a second operation and pass data to it. The current C++ standard does not allow one to register a continuation to a future. With .then, instead of waiting for the result, a continuation is "attached" to the asynchronous operation, which is invoked when the result is ready. Continuations registered using the .then function will help to avoid blocking waits or wasting threads on polling, greatly improving the responsiveness and scalability of an application.

future.then() provides the ability to sequentially compose two futures by declaring one to be the continuation of another. With .then() the antecedent future is ready (has a value or exception stored in the shared state) before the continuation starts as instructed by the lambda function.

In the example below the future<string> f2 is registered to be a continuation of future<int> f1 using the .then() member function. This operation takes a lambda function which describes how f2 should proceed after f1 is ready.

#include <boost/thread/future.hpp>
using namespace boost;
int main()
{
  future<int> f1 = async([]() { return 123; });
  future<string> f2 = f1.then([](future<int> f) { return f.get().to_string(); // here .get() won't block });
}

One key feature of this function is the ability to chain multiple asynchronous operations. In asynchronous programming, it's common to define a sequence of operations, in which each continuation executes only when the previous one completes. In some cases, the antecedent future produces a value that the continuation accepts as input. By using future.then(), creating a chain of continuations becomes straightforward and intuitive:

myFuture.then(...).then(...).then(...).

Some points to note are:

  • Each continuation will not begin until the preceding has completed.
  • If an exception is thrown, the following continuation can handle it in a try-catch block

Input Parameters:

  • Lambda function: One option which can be considered is to take two functions, one for success and one for error handling. However this option has not been retained for the moment. The lambda function takes a future as its input which carries the exception through. This makes propagating exceptions straightforward. This approach also simplifies the chaining of continuations.
  • Executor: Providing an overload to .then, to take an executor reference places great flexibility over the execution of the future in the programmer's hand. As described above, often taking a launch policy is not sufficient for powerful asynchronous operations. The lifetime of the executor must outlive the continuation.
  • Launch policy: if the additional flexibility that the executor provides is not required.

Return values: The decision to return a future was based primarily on the ability to chain multiple continuations using .then(). This benefit of composability gives the programmer incredible control and flexibility over their code. Returning a future object rather than a shared_future is also a much cheaper operation thereby improving performance. A shared_future object is not necessary to take advantage of the chaining feature. It is also easy to go from a future to a shared_future when needed using future::share().

//#include <boost/thread/future.hpp>

namespace boost
{
  namespace future_state  // EXTENSION
  {
    enum state {uninitialized, waiting, ready, moved};
  }

  enum class future_errc
  {
    broken_promise,
    future_already_retrieved,
    promise_already_satisfied,
    no_state
  };

  enum class launch
  {
    none = unspecified,
    async = unspecified,
    deferred = unspecified,
    executor = unspecified,
    inherit = unspecified,
    any = async | deferred
  };

  enum class future_status {
    ready,  timeout, deferred
  };

  namespace system
  {
    template <>
    struct is_error_code_enum<future_errc> : public true_type {};

    error_code make_error_code(future_errc e);

    error_condition make_error_condition(future_errc e);
  }

  const system::error_category& future_category();

  class future_error;

  class exceptional_ptr;

  template <typename R>
  class promise;

  template <typename R>
  void swap(promise<R>& x, promise<R>& y) noexcept;

  namespace container {
    template <class R, class Alloc>
    struct uses_allocator<promise<R>, Alloc>:: true_type;
  }

  template <typename R>
  class future;

  template <typename R>
  class shared_future;

  template <typename S>
  class packaged_task;
  template <class S> void swap(packaged_task<S>&, packaged_task<S>&) noexcept;

  template <class S, class Alloc>
  struct uses_allocator<packaged_task <S>, Alloc>;

  template <class F>
    future<typename result_of<typename decay<F>::type()>::type>
    async(F f);
  template <class F>
    future<typename result_of<typename decay<F>::type()>::type>
    async(launch policy, F f);

  template <class F, class... Args>
    future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
    async(F&& f, Args&&... args);
  template <class F, class... Args>
    future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
    async(launch policy, F&& f, Args&&... args);
  template <class Executor, class F, class... Args>
    future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
    async(Executor &ex, F&& f, Args&&... args);

  template<typename Iterator>
    void wait_for_all(Iterator begin,Iterator end); // EXTENSION
  template<typename F1,typename... FS>
    void wait_for_all(F1& f1,Fs&... fs); // EXTENSION

  template<typename Iterator>
    Iterator wait_for_any(Iterator begin,Iterator end); // EXTENSION
  template<typename F1,typename... Fs>
    unsigned wait_for_any(F1& f1,Fs&... fs); // EXTENSION

  template <class InputIterator>
    future<std::vector<typename InputIterator::value_type::value_type>>
    when_all(InputIterator first, InputIterator last);
  template <typename... T>
    future<std::tuple<decay_t<T>...> when_all(T&&... futures);
  template <class InputIterator>
    future<std::vector<typename InputIterator::value_type::value_type>>
    when_any(InputIterator first, InputIterator last); // EXTENSION
  template <typename... T>
    future<std::tuple<decay_t<T>...> when_any(T&&... futures);

  template <typename T>
    future<typename decay<T>::type> make_future(T&& value);  // DEPRECATED
  future<void> make_future();  // DEPRECATED

  template <typename T>
    future<typename decay<T>::type> make_ready_future(T&& value);  // EXTENSION
  future<void> make_ready_future();  // EXTENSION

  exceptional_ptr make_exceptional(exception_ptr ex);  // EXTENSION
  template <typename E>
    exceptional_ptr make_exceptional(E ex);  // EXTENSION
  exceptional_ptr make_exceptional();  // EXTENSION


  template <typename T>
  shared_future<typename decay<T>::type> make_shared_future(T&& value);  // DEPRECATED
  shared_future<void> make_shared_future();  // DEPRECATED
namespace future_state
{
  enum state {uninitialized, waiting, ready, moved};
}
 enum class future_errc
 {
   broken_promise = implementation defined,
   future_already_retrieved = implementation defined,
   promise_already_satisfied = implementation defined,
   no_state = implementation defined
 }


The enum values of future_errc are distinct and not zero.
enum class launch
{
  none = unspecified,
  async = unspecified,
  deferred = unspecified,
  executor = unspecified,
  inherit = unspecified,
  any = async | deferred
};

The enum type launch is a bitmask type with launch::async and launch::deferred denoting individual bits.

A future created with promise<> or with a packaged_task<> or with make_ready_future/make_exceptional_future (has no associated launch policy), has an implicit a launch policy of launch::none.

A future created by async(launch::async, ...) or ::then(launch::async, ...) has associated a launch policy launch::async. A future created by async(launch::deferred, ...) or ::then(launch::deferred, ...) has associated a launch policy launch::deferred. A future created by async(Executor, ...) or ::then(Executor, ...) or ::then(launch::executor, ...) has associated a launch policy launch::executor. A future created by async(...) or ::then(...) has associated a launch policy launch::none.

A future created by ::then(launch::inherit, ...) has associated a launch policy parent future.

The executor and the inherit launch policies have a sense only can be user only on then().

namespace system
{
  template <>
  struct is_error_code_enum<future_errc> : public true_type {};

}
namespace system
{
  error_code make_error_code(future_errc e);
}

Returns:

error_code(static_cast<int>(e), future_category()).

namespace system
{
  error_condition make_error_condition(future_errc e);
}

Returns:

error_condition(static_cast<int>(e), future_category()).

const system::error_category& future_category();

Returns:

A reference to an object of a type derived from class error_category.

Notes:

The object's default_error_condition and equivalent virtual functions behave as specified for the class system::error_category. The object's name virtual function returns a pointer to the string "future".

class future_error
    : public std::logic_error
{
public:
    future_error(system::error_code ec);

    const system::error_code& code() const no_except;
};
future_error(system::error_code ec);

Effects:

Constructs a future_error.

Postconditions:

code()==ec

Throws:

Nothing.

const system::error_code& code() const no_except;

Returns:

The value of ec that was passed to the object's constructor.

enum class future_status {
  ready,  timeout, deferred
};
class exceptional_ptr
{
public:
  exceptional_ptr();
  explicit exceptional_ptr(exception_ptr ex);
  template <class E>
  explicit exceptional_ptr(E&& ex);
};
exceptional_ptr();
explicit exceptional_ptr(exception_ptr ex);
template <class E>
explicit exceptional_ptr(E&& ex);

Effects:

The exception that is passed in to the constructor or the current exception if no parameter is moved into the constructed exceptional_ptr if it is an rvalue. Otherwise the exception is copied into the constructed exceptional_ptr.

Postconditions:

valid() == true && is_ready() = true && has_value() = false

Throws:

Nothing.

template <typename R>
class  future
{

public:
  typedef R value_type;  // EXTENSION
   future( future const& rhs) = delete;
   future& operator=( future const& rhs) = delete;

   future() noexcept;
  ~ future();

  // move support
   future( future && other) noexcept;
   future( future< future<R>>&& rhs);  // EXTENSION
   future& operator=( future && other) noexcept;

  // factories
  shared_future<R> share();

  template<typename F>
   future<typename boost::result_of<F( future)>::type>
  then(F&& func); // EXTENSION
  template<typename S, typename F>
   future<typename boost::result_of<F( future)>::type>
  then(Ex& executor, F&& func); // EXTENSION
  template<typename F>
   future<typename boost::result_of<F( future)>::type>
  then(launch policy, F&& func); // EXTENSION

  see below unwrap();  // EXTENSION
   future fallback_to();  // EXTENSION

  void swap( future& other) noexcept;

  // retrieving the value
  see below get();
  see below get_or(see below);  // EXTENSION

  exception_ptr get_exception_ptr(); // EXTENSION

  // functions to check state
  bool valid() const noexcept;
  bool is_ready() const; // EXTENSION
  bool has_exception() const; // EXTENSION
  bool has_value() const; // EXTENSION

  // waiting for the result to be ready
  void wait() const;
  template <class Rep, class Period>
  future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
  template <class Clock, class Duration>
  future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;

#if defined BOOST_THREAD_USES_DATE_TIME
  template<typename Duration>
  bool timed_wait(Duration const& rel_time) const; // DEPRECATED SINCE V3.0.0
  bool timed_wait_until(boost::system_time const& abs_time) const; // DEPRECATED SINCE V3.0.0
#endif
  typedef future_state::state state;  // EXTENSION
  state get_state() const;  // EXTENSION
};
 future();

Effects:

Constructs an uninitialized future.

Postconditions:

this->is_ready returns false. this->get_state() returns boost::future_state::uninitialized.

Throws:

Nothing.

~ future();

Effects:

Destroys *this.

Throws:

Nothing.

 future( future && other);

Effects:

Constructs a new future, and transfers ownership of the shared state associated with other to *this.

Postconditions:

this->get_state() returns the value of other->get_state() prior to the call. other->get_state() returns boost::future_state::uninitialized. If other was associated with a shared state, that result is now associated with *this. other is not associated with any shared state.

Throws:

Nothing.

Notes:

If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.

 future( future< future<R>>&& other);  // EXTENSION
[Warning] Warning

This constructor is experimental and subject to change in future versions. There are not too much tests yet, so it is possible that you can find out some trivial bugs :(

Requires:

other.valid().

[Effects:

Constructs a new future, and transfers ownership of the shared state associated with other and unwrapping the inner future (see unwrap()).

Postconditions:

this->get_state() returns the value of other->get_state() prior to the call. other->get_state() returns boost::future_state::uninitialized. The associated shared state is now unwrapped and the inner future shared state is associated with *this. other is not associated with any shared state, ! other.valid().

Throws:

Nothing.

Notes:

If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.

 future& operator=( future && other);

Effects:

Transfers ownership of the shared state associated with other to *this.

Postconditions:

this->get_state() returns the value of other->get_state() prior to the call. other->get_state() returns boost::future_state::uninitialized. If other was associated with a shared state, that result is now associated with *this. other is not associated with any shared state. If *this was associated with an asynchronous result prior to the call, that result no longer has an associated future instance.

Throws:

Nothing.

Notes:

If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.

void swap( future & other) no_except;

Effects:

Swaps ownership of the shared states associated with other and *this.

Postconditions:

this->get_state() returns the value of other->get_state() prior to the call. other->get_state() returns the value of this->get_state() prior to the call. If other was associated with a shared state, that result is now associated with *this, otherwise *this has no associated result. If *this was associated with a shared state, that result is now associated with other, otherwise other has no associated result.

Throws:

Nothing.

R get();
R&  future<R&>::get();
void  future<void>::get();

Effects:

If *this is associated with a shared state, waits until the result is ready as-if by a call to boost::future<R>::wait(), and retrieves the result (whether that is a value or an exception).

Returns:

- future<R&>::get() return the stored reference.

- future<void>::get(), there is no return value.

- future<R>::get() returns an rvalue-reference to the value stored in the shared state.

Postconditions:

this->is_ready() returns true. this->get_state() returns boost::future_state::ready.

Throws:

- boost::future_uninitialized if *this is not associated with a shared state.

- boost::thread_interrupted if the result associated with *this is not ready at the point of the call, and the current thread is interrupted.

- Any exception stored in the shared state in place of a value.

Notes:

get() is an interruption point.

R get_or(R&& v); // EXTENSION
R get_or(R const& v);  // EXTENSION
R&  future<R&>::get_or(R& v);  // EXTENSION
void  future<void>::get_or();  // EXTENSION
[Warning] Warning

These functions are experimental and subject to change in future versions. There are not too much tests yet, so it is possible that you can find out some trivial bugs :(

Effects:

If *this is associated with a shared state, waits until the result is ready as-if by a call to boost::future<R>::wait(), and depending on whether the shared state has_value() the retrieves the result.

Returns:

- future<R&>::get_or(v) return the stored reference if has_value() and the passes parameter otherwise.

- future<void>::get_or(), there is no return value, but the function doesn't throws even if the shared state contained an exception.

- future<R>::get_or(v) returns an rvalue-reference to the value stored in the shared state if has_value() and an rvalue-reference build with the parameter v.

Postconditions:

this->is_ready() returns true. this->get_state() returns boost::future_state::ready.

Throws:

- boost::future_uninitialized if *this is not associated with a shared state.

Notes:

get_or() is an interruption point.

void wait() const;

Effects:

If *this is associated with a shared state, waits until the result is ready. If the result is not ready on entry, and the result has a wait callback set, that callback is invoked prior to waiting.

Throws:

- boost::future_uninitialized if *this is not associated with a shared state.

- boost::thread_interrupted if the result associated with *this is not ready at the point of the call, and the current thread is interrupted.

- Any exception thrown by the wait callback if such a callback is called.

Postconditions:

this->is_ready() returns true. this->get_state() returns boost::future_state::ready.

Notes:

wait() is an interruption point.

template<typename Duration>
bool timed_wait(Duration const& wait_duration);
[Warning] Warning

DEPRECATED since 3.00.

Use instead wait_for.

Effects:

If *this is associated with a shared state, waits until the result is ready, or the time specified by wait_duration has elapsed. If the result is not ready on entry, and the result has a wait callback set, that callback is invoked prior to waiting.

Returns:

true if *this is associated with a shared state, and that result is ready before the specified time has elapsed, false otherwise.

Throws:

- boost::future_uninitialized if *this is not associated with a shared state.

- boost::thread_interrupted if the result associated with *this is not ready at the point of the call, and the current thread is interrupted.

- Any exception thrown by the wait callback if such a callback is called.

Postconditions:

If this call returned true, then this->is_ready() returns true and this->get_state() returns boost::future_state::ready.

Notes:

timed_wait() is an interruption point. Duration must be a type that meets the Boost.DateTime time duration requirements.

bool timed_wait(boost::system_time const& wait_timeout);
[Warning] Warning

DEPRECATED since 3.00.

Use instead wait_until.

Effects:

If *this is associated with a shared state, waits until the result is ready, or the time point specified by wait_timeout has passed. If the result is not ready on entry, and the result has a wait callback set, that callback is invoked prior to waiting.

Returns:

true if *this is associated with a shared state, and that result is ready before the specified time has passed, false otherwise.

Throws:

- boost::future_uninitialized if *this is not associated with a shared state.

- boost::thread_interrupted if the result associated with *this is not ready at the point of the call, and the current thread is interrupted.

- Any exception thrown by the wait callback if such a callback is called.

Postconditions:

If this call returned true, then this->is_ready() returns true and this->get_state() returns boost::future_state::ready.

Notes:

timed_wait() is an interruption point.

template <class Rep, class Period>
future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;

Effects:

If *this is associated with a shared state, waits until the result is ready, or the time specified by wait_duration has elapsed. If the result is not ready on entry, and the result has a wait callback set, that callback is invoked prior to waiting.

Returns:

- future_status::deferred if the shared state contains a deferred function. (Not implemented yet)

- future_status::ready if the shared state is ready.

- future_status::timeout if the function is returning because the relative timeout specified by rel_time has expired.

Throws:

- boost::future_uninitialized if *this is not associated with a shared state.

- boost::thread_interrupted if the result associated with *this is not ready at the point of the call, and the current thread is interrupted.

- Any exception thrown by the wait callback if such a callback is called.

Postconditions:

If this call returned true, then this->is_ready() returns true and this->get_state() returns boost::future_state::ready.

Notes:

wait_for() is an interruption point. Duration must be a type that meets the Boost.DateTime time duration requirements.

template <class Clock, class Duration>
future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;

Effects:

If *this is associated with a shared state, waits until the result is ready, or the time point specified by wait_timeout has passed. If the result is not ready on entry, and the result has a wait callback set, that callback is invoked prior to waiting.

Returns:

- future_status::deferred if the shared state contains a deferred function. (Not implemented yet)

- future_status::ready if the shared state is ready.

- future_status::timeout if the function is returning because the absolute timeout specified by absl_time has reached.

Throws:

- boost::future_uninitialized if *this is not associated with a shared state.

- boost::thread_interrupted if the result associated with *this is not ready at the point of the call, and the current thread is interrupted.

- Any exception thrown by the wait callback if such a callback is called.

Postconditions:

If this call returned true, then this->is_ready() returns true and this->get_state() returns boost::future_state::ready.

Notes:

wait_until() is an interruption point.

bool valid() const noexcept;

Returns:

true if *this is associated with a shared state, false otherwise.

Remarks:

The result of this function is not stable and that the future could become invalid even if the function returned true or vice-versa.

Throws:

Nothing.

bool is_ready() const;

Returns:

true if *this is associated with a shared state and that result is ready for retrieval, false otherwise.

Remarks:

The result of this function is not stable and that the future could become not ready even if the function returned true or vice-versa.

Throws:

Nothing.

bool has_value() const;

Returns:

true if *this is associated with a shared state, that result is ready for retrieval, and the result is a stored value, false otherwise.

Remarks:

The result of this function is not stable and the future could lost its value even if the function returned true or vice-versa.

Throws:

Nothing.

bool has_exception() const;

Returns:

true if *this is associated with a shared state, that result is ready for retrieval, and the result is a stored exception, false otherwise.

Remarks:

The result of this function is not stable and the future could lost its exception even if the function returned true or vice-versa.

Throws:

Nothing.

exception_ptr get_exception_ptr();

Effects:

If *this is associated with a shared state, waits until the result is ready. If the result is not ready on entry, and the result has a wait callback set, that callback is invoked prior to waiting.

Returns:

an exception_ptr, storing or not an exception.

Remarks:

The result of this function is not stable and the future could lost its exception even if the function returned a valid exception_ptr or vice-versa.

Throws:

Whatever mutex::lock()/mutex::unlock() can throw.

future_state::state get_state();

Effects:

Determine the state of the shared state associated with *this, if any.

Returns:

boost::future_state::uninitialized if *this is not associated with a shared state. boost::future_state::ready if the shared state associated with *this is ready for retrieval, boost::future_state::waiting otherwise.

Remarks:

The result of this function is not stable.

Throws:

Nothing.

shared_future<R> share();

Returns:

shared_future<R>(boost::move(*this)).

Postconditions:

this->valid() == false.

template<typename F>
 future<typename boost::result_of<F( future)>::type>
then(F&& func); // EXTENSION
template<typename S, typename F>
 future<typename boost::result_of<F( future)>::type>
then(Ex& executor, F&& func); // EXTENSION
template<typename F>
 future<typename boost::result_of<F( future)>::type>
then(launch policy, F&& func); // EXTENSION
[Warning] Warning

These functions are experimental and subject to change in future versions. There are not too much tests yet, so it is possible that you can find out some trivial bugs :(

[Note] Note

These functions are based on the N3634 - Improvements to std::future<T> and related APIs C++1y proposal by N. Gustafsson, A. Laksberg, H. Sutter, S. Mithani.

Notes:

The three functions differ only by input parameters. The first only takes a callable object which accepts a future object as a parameter. The second function takes an executor as the first parameter and a callable object as the second parameter. The third function takes a launch policy as the first parameter and a callable object as the second parameter.

Requires:

INVOKE(DECAY_COPY (std::forward<F>(func)), std::move(*this)) shall be a valid expression.

Effects:

All the functions create a shared state that is associated with the returned future object. Additionally,

- When the object's shared state is ready, the continuation INVOKE(DECAY_COPY(std::forward<F>(func)), std::move(*this)) is called depending on the overload (see below) with the call to DECAY_COPY() being evaluated in the thread that called then.

- Any value returned from the continuation is stored as the result in the shared state of the resulting future. Any exception propagated from the execution of the continuation is stored as the exceptional result in the shared state of the resulting future.

The continuation launches according to the specified policy or executor or noting.

- When the launch policy is launch::none the continuation is called on an unspecified thread of execution.

- When the launch policy is launch::async the continuation is called on a new thread of execution.

- When the launch policy is launch::deferred the continuation is called on demand.

- When the launch policy is launch::executor the continuation is called on one of the thread of execution of the executor.

- When the launch policy is launch::inherit the continuation inherits the parent's launch policy or executor.

- When the executor or launch policy is not provided (first overload) is if as if launch::none was specified.

- When the executor is provided (second overload) the continuation is called on one of the thread of execution of the executor.

- If the parent has a policy of launch::deferred and the continuation does not have a specified launch policy executor, then the parent is filled by immediately calling .wait(), and the policy of the antecedent is launch::deferred.

Returns:

An object of type future<typename boost::result_of<F( future)> that refers to the shared state created by the continuation.

Notes:

- Note that nested futures are not implicitly unwrapped yet. This could be subject to change in future versions.

- The returned futures behave as the ones returned from boost::async, the destructor of the future object returned from then will block. This could be subject to change in future versions.

Postconditions:

- The future object passed to the parameter of the continuation function is a copy of the original future.

- valid() == false on original future; valid() == true on the future returned from then.

template <typename R2>
 future<R2>  future< future<R2>>::unwrap();  // EXTENSION
template <typename R2>
 boost::shared_future<R2>  future< boost::shared_future<R2>>::unwrap();  // EXTENSION
[Warning] Warning

These functions are experimental and subject to change in future versions. There are not too much tests yet, so it is possible that you can find out some trivial bugs :(

[Note] Note

These functions are based on the N3634 - Improvements to std::future<T> and related APIs C++1y proposal by N. Gustafsson, A. Laksberg, H. Sutter, S. Mithani.

Notes:

Removes the outermost future and returns a future with the associated state been a proxy of the outer future.

Effects:

- Returns a future that becomes ready when the shared state of the outer and inner future is ready. The validity of the future returned from get() applied on the outer future cannot be established a priori. If it is not valid, this future is forced to be valid and becomes ready with an exception of type future_error, with an error code of future_errc::broken_promise.

Returns:

An object of type future with the associated state been a proxy of outer future.

Postconditions:

- The returned future has valid() == true.

template <typename R>
class shared_future
{
public:
  typedef future_state::state state; // EXTENSION
  typedef R value_type;  // EXTENSION

  shared_future() noexcept;
  ~shared_future();

  // copy support
  shared_future(shared_future const& other);
  shared_future& operator=(shared_future const& other);

  // move support
  shared_future(shared_future && other) noexcept;
  shared_future( future<R> && other) noexcept;
  shared_future& operator=(shared_future && other) noexcept;
  shared_future& operator=( future<R> && other) noexcept;

  // factories
  template<typename F>
   future<typename boost::result_of<F(shared_future)>::type>
  then(F&& func) const; // EXTENSION
  template<typename S, typename F>
   future<typename boost::result_of<F(shared_future)>::type>
  then(S& scheduler, F&& func) const; // EXTENSION
  template<typename F>
   future<typename boost::result_of<F(shared_future)>::type>
  then(launch policy, F&& func) const; // EXTENSION

  void swap(shared_future& other);

  // retrieving the value
  see below get() const;

  exception_ptr get_exception_ptr(); // EXTENSION

  // functions to check state, and wait for ready
  bool valid() const noexcept;
  bool is_ready() const noexcept; // EXTENSION
  bool has_exception() const noexcept; // EXTENSION
  bool has_value() const noexcept; // EXTENSION

  // waiting for the result to be ready
  void wait() const;
  template <class Rep, class Period>
  future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
  template <class Clock, class Duration>
  future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;

#if defined BOOST_THREAD_USES_DATE_TIME || defined BOOST_THREAD_DONT_USE_CHRONO
  template<typename Duration>
  bool timed_wait(Duration const& rel_time) const;  // DEPRECATED SINCE V3.0.0
  bool timed_wait_until(boost::system_time const& abs_time) const;  // DEPRECATED SINCE V3.0.0
#endif
  state get_state() const noexcept;  // EXTENSION

};
shared_future();

Effects:

Constructs an uninitialized shared_future.

Postconditions:

this->is_ready returns false. this->get_state() returns boost::future_state::uninitialized.

Throws:

Nothing.

const R& get() const;
R& get() const;
void get() const;

Effects:

If *this is associated with a shared state, waits until the result is ready as-if by a call to boost::shared_future<R>::wait(), and returns a const reference to the result.

Returns:

- shared_future<R&>::get() return the stored reference.

- shared_future<void>::get(), there is no return value.

- shared_future<R>::get() returns a const reference to the value stored in the shared state.

Throws:

- boost::future_uninitialized if *this is not associated with a shared state.

- boost::thread_interrupted if the result associated with *this is not ready at the point of the call, and the current thread is interrupted.

Notes:

get() is an interruption point.

void wait() const;

Effects:

If *this is associated with a shared state, waits until the result is ready. If the result is not ready on entry, and the result has a wait callback set, that callback is invoked prior to waiting.

Throws:

- boost::future_uninitialized if *this is not associated with a shared state.

- boost::thread_interrupted if the result associated with *this is not ready at the point of the call, and the current thread is interrupted.

- Any exception thrown by the wait callback if such a callback is called.

Postconditions:

this->is_ready() returns true. this->get_state() returns boost::future_state::ready.

Notes:

wait() is an interruption point.

template<typename Duration>
bool timed_wait(Duration const& wait_duration);

Effects:

If *this is associated with a shared state, waits until the result is ready, or the time specified by wait_duration has elapsed. If the result is not ready on entry, and the result has a wait callback set, that callback is invoked prior to waiting.

Returns:

true if *this is associated with a shared state, and that result is ready before the specified time has elapsed, false otherwise.

Throws:

- boost::future_uninitialized if *this is not associated with a shared state.

- boost::thread_interrupted if the result associated with *this is not ready at the point of the call, and the current thread is interrupted.

- Any exception thrown by the wait callback if such a callback is called.

Postconditions:

If this call returned true, then this->is_ready() returns true and this->get_state() returns boost::future_state::ready.

Notes:

timed_wait() is an interruption point. Duration must be a type that meets the Boost.DateTime time duration requirements.

bool timed_wait(boost::system_time const& wait_timeout);

Effects:

If *this is associated with a shared state, waits until the result is ready, or the time point specified by wait_timeout has passed. If the result is not ready on entry, and the result has a wait callback set, that callback is invoked prior to waiting.

Returns:

true if *this is associated with a shared state, and that result is ready before the specified time has passed, false otherwise.

Throws:

- boost::future_uninitialized if *this is not associated with a shared state.

- boost::thread_interrupted if the result associated with *this is not ready at the point of the call, and the current thread is interrupted.

- Any exception thrown by the wait callback if such a callback is called.

Postconditions:

If this call returned true, then this->is_ready() returns true and this->get_state() returns boost::future_state::ready.

Notes:

timed_wait() is an interruption point.

template <class Rep, class Period>
future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;

Effects:

If *this is associated with a shared state, waits until the result is ready, or the time specified by wait_duration has elapsed. If the result is not ready on entry, and the result has a wait callback set, that callback is invoked prior to waiting.

Returns:

- future_status::deferred if the shared state contains a deferred function. (Not implemented yet)

- future_status::ready if the shared state is ready.

- future_status::timeout if the function is returning because the relative timeout specified by rel_time has expired.

Throws:

- boost::future_uninitialized if *this is not associated with a shared state.

- boost::thread_interrupted if the result associated with *this is not ready at the point of the call, and the current thread is interrupted.

- Any exception thrown by the wait callback if such a callback is called.

Postconditions:

If this call returned true, then this->is_ready() returns true and this->get_state() returns boost::future_state::ready.

Notes:

timed_wait() is an interruption point. Duration must be a type that meets the Boost.DateTime time duration requirements.

template <class Clock, class Duration>
future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;

Effects:

If *this is associated with a shared state, waits until the result is ready, or the time point specified by wait_timeout has passed. If the result is not ready on entry, and the result has a wait callback set, that callback is invoked prior to waiting.

Returns:

- future_status::deferred if the shared state contains a deferred function. (Not implemented yet)

- future_status::ready if the shared state is ready.

- future_status::timeout if the function is returning because the absolute timeout specified by absl_time has reached.

Throws:

- boost::future_uninitialized if *this is not associated with a shared state.

- boost::thread_interrupted if the result associated with *this is not ready at the point of the call, and the current thread is interrupted.

- Any exception thrown by the wait callback if such a callback is called.

Postconditions:

If this call returned true, then this->is_ready() returns true and this->get_state() returns boost::future_state::ready.

Notes:

timed_wait() is an interruption point.

bool valid() const noexcept;

Returns:

true if *this is associated with a shared state, false otherwise.

Throws:

Nothing.

bool is_ready() const;

Returns:

true if *this is associated with a shared state, and that result is ready for retrieval, false otherwise.

Throws:

Whatever mutex::lock()/mutex::unlock() can throw.

bool has_value() const;

Returns:

true if *this is associated with a shared state, that result is ready for retrieval, and the result is a stored value, false otherwise.

Throws:

Whatever mutex::lock()/mutex::unlock() can throw.

bool has_exception() const;

Returns:

true if *this is associated with a shared state, that result is ready for retrieval, and the result is a stored exception, false otherwise.

Throws:

Whatever mutex::lock()/mutex::unlock() can throw.

exception_ptr get_exception_ptr();

Effects:

If *this is associated with a shared state, waits until the result is ready. If the result is not ready on entry, and the result has a wait callback set, that callback is invoked prior to waiting.

Returns:

an exception_ptr, storing or not an exception.

Throws:

Whatever mutex::lock()/mutex::unlock() can throw.

future_state::state get_state();

Effects:

Determine the state of the shared state associated with *this, if any.

Returns:

boost::future_state::uninitialized if *this is not associated with a shared state. boost::future_state::ready if the shared state associated with *this is ready for retrieval, boost::future_state::waiting otherwise.

Throws:

Whatever mutex::lock()/mutex::unlock() can throw.

template<typename F>
 future<typename boost::result_of<F(shared_future)>::type>
then(F&& func) const; // EXTENSION
template<typename S, typename F>
 future<typename boost::result_of<F(shared_future)>::type>
then(Ex& executor, F&& func) const; // EXTENSION
template<typename F>
 future<typename boost::result_of<F(shared_future)>::type>
then(launch policy, F&& func) const; // EXTENSION
[Warning] Warning

These functions are experimental and subject to change in future versions. There are not too much tests yet, so it is possible that you can find out some trivial bugs :(

[Note] Note

These functions are based on the N3634 - Improvements to std::future<T> and related APIs C++1y proposal by N. Gustafsson, A. Laksberg, H. Sutter, S. Mithani.

Notes:

The three functions differ only by input parameters. The first only takes a callable object which accepts a shared_future object as a parameter. The second function takes an executor as the first parameter and a callable object as the second parameter. The third function takes a launch policy as the first parameter and a callable object as the second parameter.

Requires:

INVOKE(DECAY_COPY (std::forward<F>(func)), *this) shall be a valid expression.

Effects:

All the functions create a shared state that is associated with the returned future object. Additionally,

- When the object's shared state is ready, the continuation INVOKE(DECAY_COPY(std::forward<F>(func)), *this) is called depending on the overload (see below) with the call to DECAY_COPY() being evaluated in the thread that called then.

- Any value returned from the continuation is stored as the result in the shared state of the resulting future. Any exception propagated from the execution of the continuation is stored as the exceptional result in the shared state of the resulting future.

The continuation launches according to the specified policy or executor or noting.

- When the launch policy is launch::none the continuation is called on an unspecified thread of execution.

- When the launch policy is launch::async the continuation is called on a new thread of execution.

- When the launch policy is launch::deferred the continuation is called on demand.

- When the launch policy is launch::executor the continuation is called on one of the thread of execution of the executor.

- When the launch policy is launch::inherit the continuation inherits the parent's launch policy or executor.

- When the executor or launch policy is not provided (first overload) is if as if launch::none was specified.

- When the executor is provided (second overload) the continuation is called on one of the thread of execution of the executor.

- If the parent has a policy of launch::deferred and the continuation does not have a specified launch policy executor, then the parent is filled by immediately calling .wait(), and the policy of the antecedent is launch::deferred.

Returns:

An object of type future<typename boost::result_of<F(shared_future)> that refers to the shared state created by the continuation.

Notes:

- Note that nested futures are not implicitly unwrapped yet. This could be subject to change in future versions.

- The returned futures behave as the ones returned from boost::async, the destructor of the future object returned from then will block. This could be subject to change in future versions.

Postconditions:

- The future object is moved to the parameter of the continuation function .

- valid() == true on original shared_future; valid() == true on the future returned from then.

template <typename R>
class promise
{
public:
  typedef R value_type;  // EXTENSION

  promise();
  template <class Allocator>
  promise(allocator_arg_t, Allocator a);
  promise & operator=(promise const& rhs) = delete;
  promise(promise const& rhs) = delete;
  ~promise();

  // Move support
  promise(promise && rhs) noexcept;;
  promise & operator=(promise&& rhs) noexcept;;

  void swap(promise& other) noexcept;
  // Result retrieval
   future<R> get_future();

  // Set the value
  void set_value(see below);
  void set_exception(boost::exception_ptr e);
  template <typename E>
  void set_exception(E e); // EXTENSION

  // setting the result with deferred notification
  void set_value_at_thread_exit(see below);
  void set_exception_at_thread_exit(exception_ptr p);
  template <typename E>
  void set_exception_at_thread_exit(E p);  // EXTENSION

  template<typename F>
  void set_wait_callback(F f); // EXTENSION
};
promise();

Effects:

Constructs a new boost::promise with no associated result.

Throws:

Nothing.

template <class Allocator>
promise(allocator_arg_t, Allocator a);

Effects:

Constructs a new boost::promise with no associated result using the allocator a.

Throws:

Nothing.

Notes:

Available only if BOOST_THREAD_FUTURE_USES_ALLOCATORS is defined.

promise(promise && other);

Effects:

Constructs a new boost::promise, and transfers ownership of the result associated with other to *this, leaving other with no associated result.

Throws:

Nothing.

Notes:

If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.

promise& operator=(promise && other);

Effects:

Transfers ownership of the result associated with other to *this, leaving other with no associated result. If there was already a result associated with *this, and that result was not ready, sets any futures associated with that result to ready with a boost::broken_promise exception as the result.

Throws:

Nothing.

Notes:

If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.

~promise();

Effects:

Destroys *this. If there was a result associated with *this, and that result is not ready, sets any futures associated with that task to ready with a boost::broken_promise exception as the result.

Throws:

Nothing.

 future<R> get_future();

Effects:

If *this was not associated with a result, allocate storage for a new shared state and associate it with *this. Returns a future associated with the result associated with *this.

Throws:

boost::future_already_retrieved if the future associated with the task has already been retrieved. std::bad_alloc if any memory necessary could not be allocated.

void set_value(R&& r);
void set_value(const R& r);
void promise<R&>::set_value(R& r);
void promise<void>::set_value();

Effects:

- If BOOST_THREAD_PROVIDES_PROMISE_LAZY is defined and if *this was not associated with a result, allocate storage for a new shared state and associate it with *this.

- Store the value r in the shared state associated with *this. Any threads blocked waiting for the asynchronous result are woken.

Postconditions:

All futures waiting on the shared state are ready and boost::future<R>::has_value() or boost::shared_future<R>::has_value() for those futures shall return true.

Throws:

- boost::promise_already_satisfied if the result associated with *this is already ready.

- boost::broken_promise if *this has no shared state.

- std::bad_alloc if the memory required for storage of the result cannot be allocated.

- Any exception thrown by the copy or move-constructor of R.

void set_exception(boost::exception_ptr e);
template <typename E>
void set_exception(E e); // EXTENSION

Effects:

- If BOOST_THREAD_PROVIDES_PROMISE_LAZY is defined and if *this was not associated with a result, allocate storage for a new shared state and associate it with *this.

- Store the exception e in the shared state associated with *this. Any threads blocked waiting for the asynchronous result are woken.

Postconditions:

All futures waiting on the shared state are ready and boost::future<R>::has_exception() or boost::shared_future<R>::has_exception() for those futures shall return true.

Throws:

- boost::promise_already_satisfied if the result associated with *this is already ready.

- boost::broken_promise if *this has no shared state.

- std::bad_alloc if the memory required for storage of the result cannot be allocated.

void set_value_at_thread_exit(R&& r);
void set_value_at_thread_exit(const R& r);
void promise<R&>::set_value_at_thread_exit(R& r);
void promise<void>::set_value_at_thread_exit();

Effects:

Stores the value r in the shared state without making that state ready immediately. Schedules that state to be made ready when the current thread exits, after all objects of thread storage duration associated with the current thread have been destroyed.

Throws:

- boost::promise_already_satisfied if the result associated with *this is already ready.

- boost::broken_promise if *this has no shared state.

- std::bad_alloc if the memory required for storage of the result cannot be allocated.

- Any exception thrown by the copy or move-constructor of R.

void set_exception_at_thread_exit(boost::exception_ptr e);
template <typename E>
void set_exception_at_thread_exit(E p);  // EXTENSION

Effects:

Stores the exception pointer p in the shared state without making that state ready immediately. Schedules that state to be made ready when the current thread exits, after all objects of thread storage duration associated with the current thread have been destroyed.

Postconditions:

All futures waiting on the shared state are ready and boost::future<R>::has_exception() or boost::shared_future<R>::has_exception() for those futures shall return true.

Throws:

- boost::promise_already_satisfied if the result associated with *this is already ready.

- boost::broken_promise if *this has no shared state.

- std::bad_alloc if the memory required for storage of the result cannot be allocated.

template<typename F>
void set_wait_callback(F f);

Preconditions:

The expression f(t) where t is a lvalue of type boost::promise shall be well-formed. Invoking a copy of f shall have the same effect as invoking f

Effects:

Store a copy of f with the shared state associated with *this as a wait callback. This will replace any existing wait callback store alongside that result. If a thread subsequently calls one of the wait functions on a future or boost::shared_future associated with this result, and the result is not ready, f(*this) shall be invoked.

Throws:

std::bad_alloc if memory cannot be allocated for the required storage.

template<typename S>
class packaged_task;
template<typename R
  , class... ArgTypes
>
class packaged_task<R(ArgTypes)>
{
public:
  packaged_task(packaged_task const&) = delete;
  packaged_task& operator=(packaged_task const&) = delete;

  // construction and destruction
  packaged_task() noexcept;

  explicit packaged_task(R(*f)(ArgTypes...));

  template <class F>
  explicit packaged_task(F&& f);

  template <class Allocator>
  packaged_task(allocator_arg_t, Allocator a, R(*f)(ArgTypes...));
  template <class F, class Allocator>
  packaged_task(allocator_arg_t, Allocator a, F&& f);

  ~packaged_task()
  {}

  // move support
  packaged_task(packaged_task&& other) noexcept;
  packaged_task& operator=(packaged_task&& other) noexcept;

  void swap(packaged_task& other) noexcept;

  bool valid() const noexcept;
  // result retrieval
   future<R> get_future();

  // execution
  void operator()(ArgTypes... );
  void make_ready_at_thread_exit(ArgTypes...);

  void reset();
  template<typename F>
  void set_wait_callback(F f);  // EXTENSION
};
packaged_task(R(*f)(ArgTypes...));

template<typename F>
packaged_task(F&&f);

Preconditions:

f() is a valid expression with a return type convertible to R. Invoking a copy of f must behave the same as invoking f.

Effects:

Constructs a new boost::packaged_task with boost::forward<F>(f) stored as the associated task.

Throws:

- Any exceptions thrown by the copy (or move) constructor of f.

- std::bad_alloc if memory for the internal data structures could not be allocated.

Notes:

The R(*f)(ArgTypes...)) overload to allow passing a function without needing to use &.

Remark:

This constructor doesn't participate in overload resolution if decay<F>::type is the same type as boost::packaged_task<R>.

template <class Allocator>
packaged_task(allocator_arg_t, Allocator a, R(*f)(ArgTypes...));
template <class F, class Allocator>
packaged_task(allocator_arg_t, Allocator a, F&& f);

Preconditions:

f() is a valid expression with a return type convertible to R. Invoking a copy of f shall behave the same as invoking f.

Effects:

Constructs a new boost::packaged_task with boost::forward<F>(f) stored as the associated task using the allocator a.

Throws:

Any exceptions thrown by the copy (or move) constructor of f. std::bad_alloc if memory for the internal data structures could not be allocated.

Notes:

Available only if BOOST_THREAD_FUTURE_USES_ALLOCATORS is defined.

Notes:

The R(*f)(ArgTypes...)) overload to allow passing a function without needing to use &.

packaged_task(packaged_task && other);

Effects:

Constructs a new boost::packaged_task, and transfers ownership of the task associated with other to *this, leaving other with no associated task.

Throws:

Nothing.

Notes:

If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.

packaged_task& operator=(packaged_task && other);

Effects:

Transfers ownership of the task associated with other to *this, leaving other with no associated task. If there was already a task associated with *this, and that task has not been invoked, sets any futures associated with that task to ready with a boost::broken_promise exception as the result.

Throws:

Nothing.

Notes:

If the compiler does not support rvalue-references, this is implemented using the boost.thread move emulation.

~packaged_task();

Effects:

Destroys *this. If there was a task associated with *this, and that task has not been invoked, sets any futures associated with that task to ready with a boost::broken_promise exception as the result.

Throws:

Nothing.

 future<R> get_future();

Effects:

Returns a future associated with the result of the task associated with *this.

Throws:

boost::task_moved if ownership of the task associated with *this has been moved to another instance of boost::packaged_task. boost::future_already_retrieved if the future associated with the task has already been retrieved.

void operator()();

Effects:

Invoke the task associated with *this and store the result in the corresponding future. If the task returns normally, the return value is stored as the shared state, otherwise the exception thrown is stored. Any threads blocked waiting for the shared state associated with this task are woken.

Postconditions:

All futures waiting on the shared state are ready

Throws:

- boost::task_moved if ownership of the task associated with *this has been moved to another instance of boost::packaged_task.

- boost::task_already_started if the task has already been invoked.

void make_ready_at_thread_exit(ArgTypes...);

Effects:

Invoke the task associated with *this and store the result in the corresponding future. If the task returns normally, the return value is stored as the shared state, otherwise the exception thrown is stored. In either case, this is done without making that state ready immediately. Schedules the shared state to be made ready when the current thread exits, after all objects of thread storage duration associated with the current thread have been destroyed.

Throws:

- boost::task_moved if ownership of the task associated with *this has been moved to another instance of boost::packaged_task.

- boost::task_already_started if the task has already been invoked.

void reset();

Effects:

Reset the state of the packaged_task so that it can be called again.

Throws:

boost::task_moved if ownership of the task associated with *this has been moved to another instance of boost::packaged_task.

template<typename F>
void set_wait_callback(F f);

Preconditions:

The expression f(t) where t is a lvalue of type boost::packaged_task shall be well-formed. Invoking a copy of f shall have the same effect as invoking f

Effects:

Store a copy of f with the task associated with *this as a wait callback. This will replace any existing wait callback store alongside that task. If a thread subsequently calls one of the wait functions on a future or boost::shared_future associated with this task, and the result of the task is not ready, f(*this) shall be invoked.

Throws:

boost::task_moved if ownership of the task associated with *this has been moved to another instance of boost::packaged_task.

template <class T>
typename decay<T>::type decay_copy(T&& v)
{
  return boost::forward<T>(v);
}

The function template async provides a mechanism to launch a function potentially in a new thread and provides the result of the function in a future object with which it shares a shared state.

Non-Variadic variant
template <class F>
   future<typename result_of<typename decay<F>::type()>::type>
  async(F&& f);
template <class F>
   future<typename result_of<typename decay<F>::type()>::type>
  async(launch policy, F&& f);
template <class Executor, class F>
   future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
  async(Executor &ex, F&& f, Args&&... args);

Requires:

decay_copy(boost::forward<F>(f))()

shall be a valid expression.

Effects

The first function behaves the same as a call to the second function with a policy argument of launch::async | launch::deferred and the same arguments for F.

The second and third functions create a shared state that is associated with the returned future object.

The further behavior of the second function depends on the policy argument as follows (if more than one of these conditions applies, the implementation may choose any of the corresponding policies):

- if policy & launch::async is non-zero - calls decay_copy(boost::forward<F>(f))() as if in a new thread of execution represented by a thread object with the calls to decay_copy() being evaluated in the thread that called async. Any return value is stored as the result in the shared state. Any exception propagated from the execution of decay_copy(boost::forward<F>(f))() is stored as the exceptional result in the shared state. The thread object is stored in the shared state and affects the behavior of any asynchronous return objects that reference that state.

- if policy & launch::deferred is non-zero - Stores decay_copy(boost::forward<F>(f)) in the shared state. This copy of f constitute a deferred function. Invocation of the deferred function evaluates boost::move(g)() where g is the stored value of decay_copy(boost::forward<F>(f)). The shared state is not made ready until the function has completed. The first call to a non-timed waiting function on an asynchronous return object referring to this shared state shall invoke the deferred function in the thread that called the waiting function. Once evaluation of boost::move(g)() begins, the function is no longer considered deferred. (Note: If this policy is specified together with other policies, such as when using a policy value of launch::async | launch::deferred, implementations should defer invocation or the selection of the policy when no more concurrency can be effectively exploited.)

- if no valid launch policy is provided the behavior is undefined.

The further behavior of the third function is as follows:

- The Executor::submit() function is given a function<void ()> which calls `INVOKE (DECAY_COPY (std::forward<F>(f)), DECAY_COPY (std::forward<Args>(args))...). The implementation of the executor is decided by the programmer.

Returns:

An object of type future<typename result_of<typename decay<F>::type()>::type> that refers to the shared state created by this call to async.

Synchronization:

Regardless of the provided policy argument,

- the invocation of async synchronizes with the invocation of f. (Note: This statement applies even when the corresponding future object is moved to another thread.); and

- the completion of the function f is sequenced before the shared state is made ready. (Note: f might not be called at all, so its completion might never happen.)

If the implementation chooses the launch::async policy,

- a call to a non-timed waiting function on an asynchronous return object that shares the shared state created by this async call shall block until the associated thread has completed, as if joined, or else time out;

- the associated thread completion synchronizes with the return from the first function that successfully detects the ready status of the shared state or with the return from the last function that releases the shared state, whichever happens first.

Throws:

system_error if policy is launch::async and the implementation is unable to start a new thread.

Error conditions:

- resource_unavailable_try_again - if policy is launch::async and the system is unable to start a new thread.

Remarks::

The first signature shall not participate in overload resolution if decay_t<F> is boost:: launch or boost::is_executor<F> is true_type`.

Variadic variant
template <class F, class... Args>
   future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
  async(F&& f, Args&&... args);
template <class F, class... Args>
   future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
  async(launch policy, F&& f, Args&&... args);
template <class Executor, class F, class... Args>
   future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
  async(Executor &ex, F&& f, Args&&... args);
[Warning] Warning

the variadic prototype is provided only on C++11 compilers supporting rvalue references, variadic templates, decltype and a standard library providing <tuple> (waiting for a boost::tuple that is move aware), and BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK is defined.

Requires:

F and each Ti in Args shall satisfy the MoveConstructible requirements.

invoke (decay_copy (boost::forward<F>(f)), decay_copy (boost::forward<Args>(args))...)

shall be a valid expression.

Effects:

- The first function behaves the same as a call to the second function with a policy argument of launch::async | launch::deferred and the same arguments for F and Args.

- The second function creates a shared state that is associated with the returned future object. The further behavior of the second function depends on the policy argument as follows (if more than one of these conditions applies, the implementation may choose any of the corresponding policies):

- if policy & launch::async is non-zero - calls invoke(decay_copy(forward<F>(f)), decay_copy (forward<Args>(args))...) as if in a new thread of execution represented by a thread object with the calls to decay_copy() being evaluated in the thread that called async. Any return value is stored as the result in the shared state. Any exception propagated from the execution of invoke(decay_copy(boost::forward<F>(f)), decay_copy (boost::forward<Args>(args))...) is stored as the exceptional result in the shared state. The thread object is stored in the shared state and affects the behavior of any asynchronous return objects that reference that state.

- if policy & launch::deferred is non-zero - Stores decay_copy(forward<F>(f)) and decay_copy(forward<Args>(args))... in the shared state. These copies of f and args constitute a deferred function. Invocation of the deferred function evaluates invoke(move(g), move(xyz)) where g is the stored value of decay_copy(forward<F>(f)) and xyz is the stored copy of decay_copy(forward<Args>(args)).... The shared state is not made ready until the function has completed. The first call to a non-timed waiting function on an asynchronous return object referring to this shared state shall invoke the deferred function in the thread that called the waiting function. Once evaluation of invoke(move(g), move(xyz)) begins, the function is no longer considered deferred.

- if no valid launch policy is provided the behaviour is undefined.

Note:

If this policy is specified together with other policies, such as when using a policy value of launch::async | launch::deferred, implementations should defer invocation or the selection of the policy when no more concurrency can be effectively exploited.

Returns:

An object of type future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type> that refers to the shared state created by this call to async.

Synchronization:

Regardless of the provided policy argument,

- the invocation of async synchronizes with the invocation of f. (Note: This statement applies even when the corresponding future object is moved to another thread.); and

- the completion of the function f is sequenced before the shared state is made ready. (Note: f might not be called at all, so its completion might never happen.)

If the implementation chooses the launch::async policy,

- a call to a waiting function on an asynchronous return object that shares the shared state created by this async call shall block until the associated thread has completed, as if joined, or else time out;

- the associated thread completion synchronizes with the return from the first function that successfully detects the ready status of the shared state or with the return from the last function that releases the shared state, whichever happens first.

Throws:

system_error if policy is launch::async and the implementation is unable to start a new thread.

Error conditions:

- resource_unavailable_try_again - if policy is launch::async and the system is unable to start a new thread.

Remarks:

The first signature shall not participate in overload resolution if decay<F>::type is boost::launch.

template<typename Iterator>
  Iterator wait_for_any(Iterator begin,Iterator end); // EXTENSION

template<typename F1,typename F2>
  unsigned wait_for_any(F1& f1,F2& f2); // EXTENSION

template<typename F1,typename F2,typename F3>
  unsigned wait_for_any(F1& f1,F2& f2,F3& f3); // EXTENSION

template<typename F1,typename F2,typename F3,typename F4>
  unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4); // EXTENSION

template<typename F1,typename F2,typename F3,typename F4,typename F5>
  unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5); // EXTENSION

Preconditions:

The types Fn shall be specializations of future or boost::shared_future, and Iterator shall be a forward iterator with a value_type which is a specialization of future or boost::shared_future.

Effects:

Waits until at least one of the specified futures is ready.

Returns:

The range-based overload returns an Iterator identifying the first future in the range that was detected as ready. The remaining overloads return the zero-based index of the first future that was detected as ready (first parameter => 0, second parameter => 1, etc.).

Throws:

boost::thread_interrupted if the current thread is interrupted. Any exception thrown by the wait callback associated with any of the futures being waited for. std::bad_alloc if memory could not be allocated for the internal wait structures.

Notes:

wait_for_any() is an interruption point.

template<typename Iterator>
  void wait_for_all(Iterator begin,Iterator end); // EXTENSION

template<typename F1,typename F2>
  void wait_for_all(F1& f1,F2& f2); // EXTENSION

template<typename F1,typename F2,typename F3>
  void wait_for_all(F1& f1,F2& f2,F3& f3); // EXTENSION

template<typename F1,typename F2,typename F3,typename F4>
  void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4); // EXTENSION

template<typename F1,typename F2,typename F3,typename F4,typename F5>
  void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5); // EXTENSION

Preconditions:

The types Fn shall be specializations of future or boost::shared_future, and Iterator shall be a forward iterator with a value_type which is a specialization of future or boost::shared_future.

Effects:

Waits until all of the specified futures are ready.

Throws:

Any exceptions thrown by a call to wait() on the specified futures.

Notes:

wait_for_all() is an interruption point.

template <class InputIterator>
  future<std::vector<typename InputIterator::value_type::value_type>>
  when_all(InputIterator first, InputIterator last);

template <typename... FutTypes>
  future<std::tuple<decay_t<FutTypes>...> when_all(FutTypes&&... futures);

Requires:

- For the first overload, InputIterator's value type shall be convertible to future<R> or shared_future<R>. All R types must be the same. If any of the future<R> or shared_future<R> objects are in invalid state (i.e. valid() == false), the behavior is undefined. - For the second overload, FutTypes is of type future<R> or shared_future<R>. The effect of calling when_all on a future or a shared_future object for which valid() == false is undefined.

Notes:

- There are two variations of when_all. The first version takes a pair of InputIterators. The second takes any arbitrary number of future<R0> and shared_future<R1> objects, where R0 and R1 need not be the same type.

- Calling the first signature of when_all where InputIterator first equals last, returns a future with an empty vector that is immediately ready.

- Calling the second signature of when_all with no arguments returns a future<tuple<>> that is immediately ready.

Effects:

- If any of the futures supplied to a call to when_all refer to deferred tasks that have not started execution, those tasks are executed before the call to when_all returns. Once all such tasks have been executed, the call to when_all returns immediately.

- The call to when_all does not wait for non-deferred tasks, or deferred tasks that have already started executing elsewhere, to complete before returning.

- Once all the futures/shared_futures supplied to the call to when_all are ready, the futures/shared_futures are moved/copied into the associated state of the future returned from the call to when_all, preserving the order of the futures supplied to when_all.

- The collection is then stored as the result in a newly created shared state.

- A new future object that refers to the shared state is created. The exact type of the future is further described below.

- The future returned by when_all will not throw an exception when calling wait() or get(), but the futures held in the output collection may.

Returns:

- future<tuple<>> if when_all is called with zero arguments.

- future<vector<future<R>>> if the input cardinality is unknown at compile and the iterator pair yields future<R>. The order of the futures in the output vector will be the same as given by the input iterator.

- future<vector<shared_future<R>>> if the input cardinality is unknown at compile time and the iterator pair yields shared_future<R>. The order of the futures in the output vector will be the same as given by the input iterator.

- future<tuple<decay_t<FutTypes>...>> if inputs are fixed in number.

Postconditions:

- All input futures valid() == false.

- All input shared future valid() == true.

- valid() == true.

template <class InputIterator>
  future<std::vector<typename InputIterator::value_type::value_type>>
  when_any(InputIterator first, InputIterator last);

template <typename... FutTypes>
  future<std::tuple<decay_t<FutTypes>...>
  when_any(FutTypes&&... futures);

Requires:

- For the first overload, InputIterator's value type shall be convertible to future<R> or shared_future<R>. All R types must be the same. If any of the future<R> or shared_future<R> objects are in invalid state (i.e. valid() == false), the behavior is undefined. - For the second overload, FutTypes is of type future<R> or shared_future<R>. The effect of calling when_any on a future or a shared_future object for which valid() == false is undefined.

Notes:

- There are two variations of when_any . The first version takes a pair of InputIterators. The second takes any arbitrary number of future<R0> and shared_future<R1> objects, where R0 and R1 need not be the same type.

- Calling the first signature of when_any where InputIterator first equals last, returns a future with an empty vector that is immediately ready.

- Calling the second signature of when_any with no arguments returns a future<tuple<>> that is immediately ready.

Effects:

- Each of the futures supplied to when_any is checked in the order supplied. If a given future is ready, then no further futures are checked, and the call to when_any returns immediately. If a given future refers to a deferred task that has not yet started execution, then no further futures are checked, that task is executed, and the call to when_any then returns immediately.

- The call to when_any does not wait for non-deferred tasks, or deferred tasks that have already started executing elsewhere, to complete before returning.

- Once at least one of the futures supplied to the call to when_any are ready, the futures are moved into the associated state of the future returned from the call to when_any, preserving the order of the futures supplied to when_any. That future is then ready.

- The collection is then stored as the result in a newly created shared state.

- A new future object that refers to the shared state is created. The exact type of the future is further described below.

- The future returned by when_any will not throw an exception when calling wait() or get(), but the futures held in the output collection may.

Returns:

- future<tuple<>> if when_any is called with zero arguments.

- future<vector<future<R>>> if the input cardinality is unknown at compile and the iterator pair yields future<R>. The order of the futures in the output vector will be the same as given by the input iterator.

- future<vector<shared_future<R>>> if the input cardinality is unknown at compile time and the iterator pair yields shared_future<R>. The order of the futures in the output vector will be the same as given by the input iterator.

- future<tuple<decat_t<FutTypes>...>> if inputs are fixed in number.

Postconditions:

- All input futures valid() == false.

- All input shared_futures valid() == true.

- valid() == true.

template <typename T>
  future<V> make_ready_future(T&& value);  // EXTENSION
future<void> make_ready_future();  // EXTENSION
template <typename T>
  future<T> make_ready_future(exception_ptr ex);  // DEPRECATED
template <typename T, typename E>
  future<T> make_ready_future(E ex);  // DEPRECATED

Remark:

where V is determined as follows: Let U be decay_t<T>. Then V is X& if U equals reference_wrapper<X>, otherwise V is U.

Effects:

- value prototype: The value that is passed into the function is moved to the shared state of the returned future if it is an rvalue. Otherwise the value is copied to the shared state of the returned future.

- exception: The exception that is passed into the function is copied to the shared state of the returned future.

.

Returns:

- a ready future with the value set with value

- a ready future with the exception set with ex

- a ready future<void> with the value set (void).

Postcondition:

- Returned future, valid() == true

- Returned future, is_ready() = true

- Returned future, has_value() = true or has_exception() depending on the prototype.

exceptional_ptr make_exceptional(exception_ptr ex);  // EXTENSION
template <typename E>
  exceptional_ptr make_exceptional(E ex);  // EXTENSION
exceptional_ptr make_exceptional();  // EXTENSION

Effects:

The exception that is passed in to the function or the current exception if no parameter is given is moved into the returned exceptional_ptr if it is an rvalue. Otherwise the exception is copied into the returned exceptional_ptr.

Returns:

An exceptional_ptr instance implicitly convertible to a future<T>

template <typename T>
  future<typename decay<T>::type> make_future(T&& value);  // DEPRECATED
future<void> make_future();  // DEPRECATED

Effects:

The value that is passed into the function is moved to the shared state of the returned function if it is an rvalue. Otherwise the value is copied to the shared state of the returned function. .

Returns:

- future<T>, if function is given a value of type T

- future<void>, if the function is not given any inputs.

Postcondition:

- Returned future<T>, valid() == true

- Returned future<T>, is_ready() = true

See:

make_ready_future()

template <typename T>
  shared_future<typename decay<T>::type> make_shared_future(T&& value);  // DEPRECATED
shared_future<void> make_shared_future();  // DEPRECATED

Effects:

The value that is passed in to the function is moved to the shared state of the returned function if it is an rvalue. Otherwise the value is copied to the shared state of the returned function. .

Returns:

- shared_future<T>, if function is given a value of type T

- shared_future<void>, if the function is not given any inputs.

Postcondition:

- Returned shared_future<T>, valid() == true

- Returned shared_future<T>, is_ready() = true

See:

make_ready_future() and future<>::share()


PrevUpHomeNext