33 Thread support library [thread]

33.6 Futures [futures]

33.6.7 Class template future [futures.unique_future]

The class template future defines a type for asynchronous return objects which do not share their shared state with other asynchronous return objects.
A default-constructed future object has no shared state.
A future object with shared state can be created by functions on asynchronous providers ([futures.state]) or by the move constructor and shares its shared state with the original asynchronous provider.
The result (value or exception) of a future object can be set by calling a respective function on an object that shares the same shared state.
[Note
:
Member functions of future do not synchronize with themselves or with member functions of shared_­future.
end note
]
The effect of calling any member function other than the destructor, the move-assignment operator, share, or valid on a future object for which valid() == false is undefined.
[Note
:
It is valid to move from a future object for which valid() == false.
end note
]
[Note
:
Implementations are encouraged to detect this case and throw an object of type future_­error with an error condition of future_­errc​::​no_­state.
end note
]
namespace std {
  template <class R>
  class future {
  public:
    future() noexcept;
    future(future&&) noexcept;
    future(const future& rhs) = delete;
    ~future();
    future& operator=(const future& rhs) = delete;
    future& operator=(future&&) noexcept;
    shared_future<R> share() noexcept;

    // retrieving the value
    see below get();

    // functions to check state
    bool valid() const noexcept;

    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;
  };
}
The implementation shall provide the template future and two specializations, future<R&> and future<​void>.
These differ only in the return type and return value of the member function get, as set out in its description, below.
future() noexcept;
Effects: Constructs an empty future object that does not refer to a shared state.
Postconditions: valid() == false.
future(future&& rhs) noexcept;
Effects: Move constructs a future object that refers to the shared state that was originally referred to by rhs (if any).
Postconditions:
  • valid() returns the same value as rhs.valid() prior to the constructor invocation.
  • rhs.valid() == false.
~future();
Effects:
future& operator=(future&& rhs) noexcept;
Effects:
Postconditions:
  • valid() returns the same value as rhs.valid() prior to the assignment.
  • rhs.valid() == false.
shared_future<R> share() noexcept;
Returns: shared_­future<R>(std​::​move(*this)).
Postconditions: valid() == false.
R future::get(); R& future<R&>::get(); void future<void>::get();
[Note
:
As described above, the template and its two required specializations differ only in the return type and return value of the member function get.
end note
]
Effects:
  • wait()s until the shared state is ready, then retrieves the value stored in the shared state;
  • releases any shared state ([futures.state]).
Returns:
  • future​::​get() returns the value v stored in the object's shared state as std​::​move(v).
  • future<R&>​::​get() returns the reference stored as value in the object's shared state.
  • future<void>​::​get() returns nothing.
Throws: the stored exception, if an exception was stored in the shared state.
Postconditions: valid() == false.
bool valid() const noexcept;
Returns: true only if *this refers to a shared state.
void wait() const;
Effects: Blocks until the shared state is ready.
template <class Rep, class Period> future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
Effects: None if the shared state contains a deferred function ([futures.async]), otherwise blocks until the shared state is ready or until the relative timeout ([thread.req.timing]) specified by rel_­time has expired.
Returns:
  • future_­status​::​deferred if the shared state contains a deferred function.
  • future_­status​::​ready if the shared state is ready.
  • future_­status​::​timeout if the function is returning because the relative timeout ([thread.req.timing]) specified by rel_­time has expired.
Throws: timeout-related exceptions ([thread.req.timing]).
template <class Clock, class Duration> future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
Effects: None if the shared state contains a deferred function ([futures.async]), otherwise blocks until the shared state is ready or until the absolute timeout ([thread.req.timing]) specified by abs_­time has expired.
Returns:
  • future_­status​::​deferred if the shared state contains a deferred function.
  • future_­status​::​ready if the shared state is ready.
  • future_­status​::​timeout if the function is returning because the absolute timeout ([thread.req.timing]) specified by abs_­time has expired.
Throws: timeout-related exceptions ([thread.req.timing]).