| Home | Libraries | People | FAQ | More

#### Future

A future provides a mechanism to access the result of an asynchronous operation.

###### shared state

Behind a `promise<>` and its `future<>` lies an unspecified object called their shared state. The shared state is what will actually hold the async result (or the exception).

The shared state is instantiated along with the `promise<>`.

Aside from its originating `promise<>`, a `future<>` holds a unique reference to a particular shared state. However, multiple `shared_future<>` instances can reference the same underlying shared state.

As `packaged_task<>` and `fibers::async()` are implemented using `promise<>`, discussions of shared state apply to them as well.

###### Enumeration `future_status`

Timed wait-operations (`future::wait_for()` and `future::wait_until()`) return the state of the future.

    enum class future_status {
        ready,
        timeout,
        deferred  // not supported yet
    };

###### `ready`

Effects:

  The shared state is ready.

###### `timeout`

Effects:

  The shared state did not become ready before timeout has passed.

| Note
Deferred futures are not supported.

##### Template `future<>`

A `future<>` contains a shared state which is not shared with any other future.

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

    namespace boost {
    namespace fibers {

    template< typename R >
    class future {
    public:
        future() noexcept;

        future( future const& other) = delete;

        future & operator=( future const& other) = delete;

        future( future && other) noexcept;

        future & operator=( future && other) noexcept;

        ~future();

        bool valid() const noexcept;

        shared_future< R > share();

        R get();    // member only of generic future template
        R & get();  // member only of future< R & > template specialization
        void get(); // member only of future< void > template specialization

        std::exception_ptr get_exception_ptr();

        void wait() const;

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

        template< typename Clock, typename Duration >
        future_status wait_until(
            std::chrono::time_point< Clock, Duration > const& timeout_time) const;
    };

    }}

###### Default constructor

    future() noexcept;

Effects:

  Creates a future with no shared state. After construction `false == valid()`.

Throws:

  Nothing.

###### Move constructor

    future( future && other) noexcept;

Effects:

  Constructs a future with the shared state of other. After construction `false == other.valid()`.

Throws:

  Nothing.

###### Destructor

    ~future();

Effects:

  Destroys the future; ownership is abandoned.

Note:

  `~future()` does not block the calling fiber.

Consider a sequence such as:

1. instantiate `promise<>`
2. obtain its `future<>` via `promise::get_future()`
3. launch `fiber`, capturing `promise<>`
4. destroy `future<>`
5. call `promise::set_value()`

The final `set_value()` call succeeds, but the value is silently discarded: no additional `future<>` can be obtained from that `promise<>`.

##### Member function `operator=`()

    future & operator=( future && other) noexcept;

Effects:

  Moves the shared state of other to `this`. After the assignment, `false == other.valid()`.

Throws:

  Nothing.

##### Member function `valid`()

    bool valid() const noexcept;

Effects:

  Returns `true` if future contains a shared state.

Throws:

  Nothing.

##### Member function `share`()

    shared_future< R > share();

Effects:

  Move the state to a `shared_future<>`.

Returns:

  a `shared_future<>` containing the shared state formerly belonging to `*this`.

Postcondition:

  `false == valid()`

Throws:

  `future_error` with error condition `future_errc::no_state`.

##### Member function `get`()

    R get();    // member only of generic future template
    R & get();  // member only of future< R & > template specialization
    void get(); // member only of future< void > template specialization

Precondition:

  `true == valid()`

Returns:

  Waits until `promise::set_value()` or `promise::set_exception()` is called. If `promise::set_value()` is called, returns the value. If `promise::set_exception()` is called, throws the indicated exception.

Postcondition:

  `false == valid()`

Throws:

  `future_error` with error condition `future_errc::no_state`, `future_errc::broken_promise`. Any exception passed to `promise::set_exception()`.

##### Member function `get_exception_ptr`()

    std::exception_ptr get_exception_ptr();

Precondition:

  `true == valid()`

Returns:

  Waits until `promise::set_value()` or `promise::set_exception()` is called. If `set_value()` is called, returns a default-constructed `std::exception_ptr`. If `set_exception()` is called, returns the passed `std::exception_ptr`.

Throws:

  `future_error` with error condition `future_errc::no_state`.

Note:

  `get_exception_ptr()` does not invalidate the `future`. After calling `get_exception_ptr()`, you may still call `future::get()`.

##### Member function `wait`()

    void wait();

Effects:

  Waits until `promise::set_value()` or `promise::set_exception()` is called.

Throws:

  `future_error` with error condition `future_errc::no_state`.

##### Templated member function `wait_for`()

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

Effects:

  Waits until `promise::set_value()` or `promise::set_exception()` is called, or `timeout_duration` has passed.

Result:

  A `future_status` is returned indicating the reason for returning.

Throws:

  `future_error` with error condition `future_errc::no_state` or timeout-related exceptions.

##### Templated member function `wait_until`()

    template< typename Clock, typename Duration >
    future_status wait_until( std::chrono::time_point< Clock, Duration > const& timeout_time) const;

Effects:

  Waits until `promise::set_value()` or `promise::set_exception()` is called, or `timeout_time` has passed.

Result:

  A `future_status` is returned indicating the reason for returning.

Throws:

  `future_error` with error condition `future_errc::no_state` or timeout-related exceptions.

##### Template `shared_future<>`

A `shared_future<>` contains a shared state which might be shared with other `shared_future<>` instances.

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

    namespace boost {
    namespace fibers {

    template< typename R >
    class shared_future {
    public:
        shared_future() noexcept;

        ~shared_future();

        shared_future( shared_future const& other);

        shared_future( future< R > && other) noexcept;

        shared_future( shared_future && other) noexcept;

        shared_future & operator=( shared_future && other) noexcept;

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

        shared_future & operator=( shared_future const& other) noexcept;

        bool valid() const noexcept;

        R const& get(); // member only of generic shared_future template
        R & get();      // member only of shared_future< R & > template specialization
        void get();     // member only of shared_future< void > template specialization

        std::exception_ptr get_exception_ptr();

        void wait() const;

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

        template< typename Clock, typename Duration >
        future_status wait_until(
            std::chrono::time_point< Clock, Duration > const& timeout_time) const;
    };

    }}

###### Default constructor

    shared_future();

Effects:

  Creates a shared_future with no shared state. After construction `false == valid()`.

Throws:

  Nothing.

###### Move constructor

    shared_future( future< R > && other) noexcept;
    shared_future( shared_future && other) noexcept;

Effects:

  Constructs a shared_future with the shared state of other. After construction `false == other.valid()`.

Throws:

  Nothing.

###### Copy constructor

    shared_future( shared_future const& other) noexcept;

Effects:

  Constructs a shared_future with the shared state of other. After construction `other.valid()` is unchanged.

Throws:

  Nothing.

###### Destructor

    ~shared_future();

Effects:

  Destroys the shared_future; ownership is abandoned if not shared.

Note:

  `~shared_future()` does not block the calling fiber.

##### Member function `operator=`()

    shared_future & operator=( future< R > && other) noexcept;
    shared_future & operator=( shared_future && other) noexcept;
    shared_future & operator=( shared_future const& other) noexcept;

Effects:

  Moves or copies the shared state of other to `this`. After the assignment, the state of `other.valid()` depends on which overload was invoked: unchanged for the overload accepting `shared_future const&`, otherwise `false`.

Throws:

  Nothing.

##### Member function `valid`()

    bool valid() const noexcept;

Effects:

  Returns `true` if shared_future contains a shared state.

Throws:

  Nothing.

##### Member function `get`()

    R const& get(); // member only of generic shared_future template
    R & get();      // member only of shared_future< R & > template specialization
    void get();     // member only of shared_future< void > template specialization

Precondition:

  `true == valid()`

Returns:

  Waits until `promise::set_value()` or `promise::set_exception()` is called. If `promise::set_value()` is called, returns the value. If `promise::set_exception()` is called, throws the indicated exception.

Postcondition:

  `false == valid()`

Throws:

  `future_error` with error condition `future_errc::no_state`, `future_errc::broken_promise`. Any exception passed to `promise::set_exception()`.

##### Member function `get_exception_ptr`()

    std::exception_ptr get_exception_ptr();

Precondition:

  `true == valid()`

Returns:

  Waits until `promise::set_value()` or `promise::set_exception()` is called. If `set_value()` is called, returns a default-constructed `std::exception_ptr`. If `set_exception()` is called, returns the passed `std::exception_ptr`.

Throws:

  `future_error` with error condition `future_errc::no_state`.

Note:

  `get_exception_ptr()` does not invalidate the `shared_future`. After calling `get_exception_ptr()`, you may still call `shared_future::get()`.

##### Member function `wait`()

    void wait();

Effects:

  Waits until `promise::set_value()` or `promise::set_exception()` is called.

Throws:

  `future_error` with error condition `future_errc::no_state`.

##### Templated member function `wait_for`()

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

Effects:

  Waits until `promise::set_value()` or `promise::set_exception()` is called, or `timeout_duration` has passed.

Result:

  A `future_status` is returned indicating the reason for returning.

Throws:

  `future_error` with error condition `future_errc::no_state` or timeout-related exceptions.

##### Templated member function `wait_until`()

    template< typename Clock, typename Duration >
    future_status wait_until( std::chrono::time_point< Clock, Duration > const& timeout_time) const;

Effects:

  Waits until `promise::set_value()` or `promise::set_exception()` is called, or `timeout_time` has passed.

Result:

  A `future_status` is returned indicating the reason for returning.

Throws:

  `future_error` with error condition `future_errc::no_state` or timeout-related exceptions.

##### Non-member function `fibers::async()`

    #include <boost/fiber/future/async.hpp>

    namespace boost {
    namespace fibers {

    template< class Function, class ... Args >
    future<
        std::result_of_t<
            std::decay_t< Function >( std::decay_t< Args > ... )
        >
    >
    async( Function && fn, Args && ... args);

    template< class Function, class ... Args >
    future<
        std::result_of_t<
            std::decay_t< Function >( std::decay_t< Args > ... )
        >
    >
    async( launch policy, Function && fn, Args && ... args);

    template< typename StackAllocator, class Function, class ... Args >
    future<
        std::result_of_t<
            std::decay_t< Function >( std::decay_t< Args > ... )
        >
    >
    async( launch policy, std::allocator_arg_t, StackAllocator salloc,
           Function && fn, Args && ... args);

    template< typename StackAllocator, typename Allocator, class Function, class ... Args >
    future<
        std::result_of_t<
            std::decay_t< Function >( std::decay_t< Args > ... )
        >
    >
    async( launch policy, std::allocator_arg_t, StackAllocator salloc,
           Allocator alloc, Function && fn, Args && ... args);

    }}

Effects:

  Executes `fn` in a `fiber` and returns an associated `future<>`.

Result:

      future<
          std::result_of_t<
              std::decay_t< Function >( std::decay_t< Args > ... )
          >
      >

  representing the shared state associated with the asynchronous execution of `fn`.

Throws:

  `fiber_error` or `future_error` if an error occurs.

Notes:

  The overloads accepting `std::allocator_arg_t` use the passed `StackAllocator` when constructing the launched `fiber`. The overloads accepting `launch` use the passed `launch` when constructing the launched `fiber`. The default `launch` is `post`, as for the `fiber` constructor.

| Note
Deferred futures are not supported.