Files
cppdraft_translate/cppdraft/futures.md
2025-10-25 03:02:53 +03:00

2004 lines
74 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[futures]
# 32 Concurrency support library [[thread]](./#thread)
## 32.10 Futures [futures]
### [32.10.1](#overview) Overview [[futures.overview]](futures.overview)
[1](#overview-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11126)
[futures] describes components that a C++ program can use to retrieve in one thread the
result (value or exception) from a function that has run in the same thread or another thread[.](#overview-1.sentence-1)
[*Note [1](#overview-note-1)*:
These components are not restricted to multi-threaded programs but can be useful in
single-threaded programs as well[.](#overview-1.sentence-2)
— *end note*]
### [32.10.2](#future.syn) Header <future> synopsis [[future.syn]](future.syn)
[🔗](#header:%3cfuture%3e)
namespace std {enum class [future_errc](#lib:future_errc "32.10.2Header <future> synopsis[future.syn]") {[broken_promise](#lib:future_errc,broken_promise "32.10.2Header <future> synopsis[future.syn]") = *implementation-defined*, [future_already_retrieved](#lib:future_errc,future_already_retrieved "32.10.2Header <future> synopsis[future.syn]") = *implementation-defined*, [promise_already_satisfied](#lib:future_errc,promise_already_satisfied "32.10.2Header <future> synopsis[future.syn]") = *implementation-defined*, [no_state](#lib:future_errc,no_state "32.10.2Header <future> synopsis[future.syn]") = *implementation-defined*}; enum class [launch](#lib:launch "32.10.2Header <future> synopsis[future.syn]") : *unspecified* {[async](#lib:launch,async "32.10.2Header <future> synopsis[future.syn]") = *unspecified*, [deferred](#lib:launch,deferred "32.10.2Header <future> synopsis[future.syn]") = *unspecified*, *implementation-defined*}; enum class [future_status](#lib:future_status "32.10.2Header <future> synopsis[future.syn]") {[ready](#lib:future_status,ready "32.10.2Header <future> synopsis[future.syn]"), [timeout](#lib:future_status,timeout "32.10.2Header <future> synopsis[future.syn]"), [deferred](#lib:future_status,deferred "32.10.2Header <future> synopsis[future.syn]")}; // [[futures.errors]](#errors "32.10.3Error handling"), error handlingtemplate<> struct is_error_code_enum<future_errc> : public true_type { };
error_code make_error_code(future_errc e) noexcept;
error_condition make_error_condition(future_errc e) noexcept; const error_category& future_category() noexcept; // [[futures.future.error]](#future.error "32.10.4Class future_­error"), class future_errorclass future_error; // [[futures.promise]](#promise "32.10.6Class template promise"), class template promisetemplate<class R> class promise; template<class R> class promise<R&>; template<> class promise<void>; template<class R>void swap(promise<R>& x, promise<R>& y) noexcept; // [[futures.unique.future]](#unique.future "32.10.7Class template future"), class template futuretemplate<class R> class future; template<class R> class future<R&>; template<> class future<void>; // [[futures.shared.future]](#shared.future "32.10.8Class template shared_­future"), class template shared_futuretemplate<class R> class shared_future; template<class R> class shared_future<R&>; template<> class shared_future<void>; // [[futures.task]](#task "32.10.10Class template packaged_­task"), class template packaged_tasktemplate<class> class packaged_task; // *not defined*template<class R, class... ArgTypes>class packaged_task<R(ArgTypes...)>; template<class R, class... ArgTypes>void swap(packaged_task<R(ArgTypes...)>&, packaged_task<R(ArgTypes...)>&) noexcept; // [[futures.async]](#async "32.10.9Function template async"), function template asynctemplate<class F, class... Args> future<invoke_result_t<decay_t<F>, decay_t<Args>...>> async(F&& f, Args&&... args); template<class F, class... Args> future<invoke_result_t<decay_t<F>, decay_t<Args>...>> async(launch policy, F&& f, Args&&... args);}
[1](#future.syn-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11204)
The enum type launch is a bitmask type ([[bitmask.types]](bitmask.types "16.3.3.3.3Bitmask types")) with
elements launch::async and launch::deferred[.](#future.syn-1.sentence-1)
[*Note [1](#future.syn-note-1)*:
Implementations can provide bitmasks to specify restrictions on task
interaction by functions launched by async() applicable to a
corresponding subset of available launch policies[.](#future.syn-1.sentence-2)
Implementations can extend
the behavior of the first overload of async() by adding their extensions
to the launch policy under the “as if” rule[.](#future.syn-1.sentence-3)
— *end note*]
[2](#future.syn-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11215)
The enum values of future_errc are distinct and not zero[.](#future.syn-2.sentence-1)
### [32.10.3](#errors) Error handling [[futures.errors]](futures.errors)
[🔗](#lib:future_category)
`const error_category& future_category() noexcept;
`
[1](#errors-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11226)
*Returns*: A reference to an object of a type derived from class error_category[.](#errors-1.sentence-1)
[2](#errors-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11230)
The object's default_error_condition and equivalent virtual functions shall
behave as specified for the class error_category[.](#errors-2.sentence-1)
The object's name virtual function returns a pointer to the string "future"[.](#errors-2.sentence-2)
[🔗](#lib:make_error_code,future_errc)
`error_code make_error_code(future_errc e) noexcept;
`
[3](#errors-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11242)
*Returns*: error_code(static_cast<int>(e), future_category())[.](#errors-3.sentence-1)
[🔗](#lib:make_error_condition,future_errc)
`error_condition make_error_condition(future_errc e) noexcept;
`
[4](#errors-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11253)
*Returns*: error_condition(static_cast<int>(e), future_category())[.](#errors-4.sentence-1)
### [32.10.4](#future.error) Class future_error [[futures.future.error]](futures.future.error)
[🔗](#lib:future_error)
namespace std {class future_error : public logic_error {public:explicit future_error(future_errc e); const error_code& code() const noexcept; const char* what() const noexcept; private: error_code ec_; // *exposition only*};}
[🔗](#lib:future_error,constructor)
`explicit future_error(future_errc e);
`
[1](#future.error-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11282)
*Effects*: Initializes ec_ with make_error_code(e)[.](#future.error-1.sentence-1)
[🔗](#lib:code,future_error)
`const error_code& code() const noexcept;
`
[2](#future.error-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11293)
*Returns*: ec_[.](#future.error-2.sentence-1)
[🔗](#lib:what,future_error)
`const char* what() const noexcept;
`
[3](#future.error-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11304)
*Returns*: An ntbs incorporating code().message()[.](#future.error-3.sentence-1)
### [32.10.5](#state) Shared state [[futures.state]](futures.state)
[1](#state-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11311)
Many of the classes introduced in subclause [futures] use some state to communicate results[.](#state-1.sentence-1)
This
[*shared state*](#def:future,shared_state "32.10.5Shared state[futures.state]") consists of some state information and some (possibly not
yet evaluated) [*result*](#def:result), which can be a (possibly void) value or an exception[.](#state-1.sentence-2)
[*Note [1](#state-note-1)*:
Futures, promises, and tasks defined in this Clause reference such shared state[.](#state-1.sentence-3)
— *end note*]
[2](#state-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11320)
[*Note [2](#state-note-2)*:
The result can be any kind of object including a function to compute that result,
as used by async when policy is launch::deferred[.](#state-2.sentence-1)
— *end note*]
[3](#state-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11326)
An [*asynchronous return object*](#def:asynchronous_return_object "32.10.5Shared state[futures.state]") is an object that reads results from a
shared state[.](#state-3.sentence-1)
A [*waiting function*](#def:function,waiting "32.10.5Shared state[futures.state]") of an asynchronous return object is one
that potentially blocks to wait for the shared state to be made
ready[.](#state-3.sentence-2)
If a waiting function can return before the state is made ready because of a
timeout ([[thread.req.lockable]](thread.req.lockable "32.2.5Requirements for Cpp17Lockable types")), then it is a [*timed waiting function*](#def:timed_waiting_function), otherwise
it is a [*non-timed waiting function*](#def:non-timed_waiting_function)[.](#state-3.sentence-3)
[4](#state-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11335)
An [*asynchronous provider*](#def:asynchronous_provider "32.10.5Shared state[futures.state]") is an object that provides a result to a shared
state[.](#state-4.sentence-1)
The result of a shared state is set by
respective functions on the asynchronous provider[.](#state-4.sentence-2)
[*Example [1](#state-example-1)*:
Promises and tasks are examples of asynchronous providers[.](#state-4.sentence-3)
— *end example*]
The means of setting the result of a shared state is specified
in the description of those classes and functions that create such a state object[.](#state-4.sentence-4)
[5](#state-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11346)
When an asynchronous return object or an asynchronous provider is said to release its
shared state, it means:
- [(5.1)](#state-5.1)
if the return object or provider holds the last reference to its shared state,
the shared state is destroyed; and
- [(5.2)](#state-5.2)
the return object or provider gives up its reference to its shared state; and
- [(5.3)](#state-5.3)
these actions will not block for the shared state to become ready, except that it
may block if all of the following are true: the shared state was created by a call tostd::async, the shared state is not yet ready, and this was the last reference
to the shared state[.](#state-5.sentence-1)
[6](#state-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11363)
When an asynchronous provider is said to make its shared state ready, it means:
- [(6.1)](#state-6.1)
first, the provider marks its shared state as ready; and
- [(6.2)](#state-6.2)
second, the provider unblocks any execution agents waiting for its shared
state to become ready[.](#state-6.sentence-1)
[7](#state-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11373)
When an asynchronous provider is said to abandon its shared state, it means:
- [(7.1)](#state-7.1)
first, if that state is not ready, the provider
* [(7.1.1)](#state-7.1.1)
stores an exception object of type future_error with an error condition ofbroken_promise within its shared state; and then
* [(7.1.2)](#state-7.1.2)
makes its shared state ready;
- [(7.2)](#state-7.2)
second, the provider releases its shared state[.](#state-7.sentence-1)
[8](#state-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11389)
A shared state is [*ready*](#def:ready "32.10.5Shared state[futures.state]") only if it holds a value or an exception ready for
retrieval[.](#state-8.sentence-1)
Waiting for a shared state to become ready may invoke code to compute the result on
the waiting thread if so specified in the description of the class or function that creates
the state object[.](#state-8.sentence-2)
[9](#state-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11396)
Calls to functions that successfully set the stored result of a shared
state [synchronize with](intro.multithread#def:synchronize_with "6.10.2Multi-threaded executions and data races[intro.multithread]") calls to functions
successfully detecting the ready state resulting from that setting[.](#state-9.sentence-1)
The storage of the result
(whether normal or exceptional) into the shared state[synchronizes with](intro.multithread#def:synchronize_with "6.10.2Multi-threaded executions and data races[intro.multithread]") the successful return from a call to a waiting function on the shared state[.](#state-9.sentence-2)
[10](#state-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11405)
Some functions (e.g., promise::set_value_at_thread_exit) delay making
the shared state ready until the calling thread exits[.](#state-10.sentence-1)
The destruction of
each of that thread's objects with [thread storage duration](basic.stc.thread "6.8.6.3Thread storage duration[basic.stc.thread]") is sequenced before making that shared state ready[.](#state-10.sentence-2)
[11](#state-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11411)
Access to the result of the same shared state may [conflict](intro.multithread#def:conflict "6.10.2Multi-threaded executions and data races[intro.multithread]")[.](#state-11.sentence-1)
[*Note [3](#state-note-3)*:
This explicitly specifies that the result of the shared state is
visible in the objects that reference this state in the sense of data race
avoidance ([[res.on.data.races]](res.on.data.races "16.4.6.10Data race avoidance"))[.](#state-11.sentence-2)
For example, concurrent accesses through
references returned by shared_future::get() ([[futures.shared.future]](#shared.future "32.10.8Class template shared_­future"))
must either use read-only operations or provide additional synchronization[.](#state-11.sentence-3)
— *end note*]
### [32.10.6](#promise) Class template promise [[futures.promise]](futures.promise)
[🔗](#lib:promise)
namespace std {template<class R>class promise {public: promise(); template<class Allocator> promise(allocator_arg_t, const Allocator& a);
promise(promise&& rhs) noexcept;
promise(const promise&) = delete; ~promise(); // assignment promise& operator=(promise&& rhs) noexcept;
promise& operator=(const promise&) = delete; void swap(promise& other) noexcept; // retrieving the result future<R> get_future(); // setting the resultvoid set_value(*see below*); void set_exception(exception_ptr p); // setting the result with deferred notificationvoid set_value_at_thread_exit(*see below*); void set_exception_at_thread_exit(exception_ptr p); };}
[1](#promise-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11455)
For the primary template, R shall be an object type that
meets the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2Template argument requirements[utility.arg.requirements]") requirements[.](#promise-1.sentence-1)
[2](#promise-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11459)
The implementation provides the template promise and two specializations,promise<R&> and promise<void>[.](#promise-2.sentence-1)
These differ only in the argument type
of the member functions set_value and set_value_at_thread_exit,
as set out in their descriptions, below[.](#promise-2.sentence-2)
[3](#promise-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11465)
The set_value, set_exception, set_value_at_thread_exit,
and set_exception_at_thread_exit member functions behave as though
they acquire a single mutex associated with the promise object while updating the
promise object[.](#promise-3.sentence-1)
[🔗](#lib:promise,constructor)
`promise();
template<class Allocator>
promise(allocator_arg_t, const Allocator& a);
`
[4](#promise-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11479)
*Effects*: Creates a shared state[.](#promise-4.sentence-1)
The second
constructor uses the allocator a to allocate memory for the shared
state[.](#promise-4.sentence-2)
[🔗](#lib:promise,constructor_)
`promise(promise&& rhs) noexcept;
`
[5](#promise-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11492)
*Effects*: Transfers ownership of the shared state
of rhs (if any) to the newly-constructed object[.](#promise-5.sentence-1)
[6](#promise-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11497)
*Postconditions*: rhs has no shared state[.](#promise-6.sentence-1)
[🔗](#lib:promise,destructor)
`~promise();
`
[7](#promise-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11508)
*Effects*: Abandons any shared state ([[futures.state]](#state "32.10.5Shared state"))[.](#promise-7.sentence-1)
[🔗](#lib:operator=,promise)
`promise& operator=(promise&& rhs) noexcept;
`
[8](#promise-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11519)
*Effects*: Abandons any shared state ([[futures.state]](#state "32.10.5Shared state")) and then as ifpromise(std::move(rhs)).swap(*this)[.](#promise-8.sentence-1)
[9](#promise-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11524)
*Returns*: *this[.](#promise-9.sentence-1)
[🔗](#lib:swap,promise)
`void swap(promise& other) noexcept;
`
[10](#promise-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11535)
*Effects*: Exchanges the shared state of *this and other[.](#promise-10.sentence-1)
[11](#promise-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11539)
*Postconditions*: *this has the shared state (if any) that other had
prior to the call to swap[.](#promise-11.sentence-1)
other has the shared state (if any) that*this had prior to the call to swap[.](#promise-11.sentence-2)
[🔗](#lib:get_future,promise)
`future<R> get_future();
`
[12](#promise-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11552)
*Synchronization*: Calls to this function do not introduce
data races ([[intro.multithread]](intro.multithread "6.10.2Multi-threaded executions and data races")) with calls toset_value,set_exception,set_value_at_thread_exit, orset_exception_at_thread_exit[.](#promise-12.sentence-1)
[*Note [1](#promise-note-1)*:
Such calls need not synchronize with each other[.](#promise-12.sentence-2)
— *end note*]
[13](#promise-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11564)
*Returns*: A future<R> object with the same shared state as*this[.](#promise-13.sentence-1)
[14](#promise-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11569)
*Throws*: future_error if *this has no shared state or ifget_future has already been called on a promise with the same
shared state as *this[.](#promise-14.sentence-1)
[15](#promise-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11575)
*Error conditions*:
- [(15.1)](#promise-15.1)
future_already_retrieved if get_future has already been called on
a promise with the same shared state as *this[.](#promise-15.1.sentence-1)
- [(15.2)](#promise-15.2)
no_state if *this has no shared state[.](#promise-15.2.sentence-1)
[🔗](#lib:set_value,promise)
`void promise::set_value(const R& r);
void promise::set_value(R&& r);
void promise<R&>::set_value(R& r);
void promise<void>::set_value();
`
[16](#promise-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11594)
*Effects*: Atomically stores the value r in the shared state and
makes that state ready ([[futures.state]](#state "32.10.5Shared state"))[.](#promise-16.sentence-1)
[17](#promise-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11599)
*Throws*:
- [(17.1)](#promise-17.1)
future_error if its shared state
already has a stored value or exception, or
- [(17.2)](#promise-17.2)
for the first version, any exception thrown by the constructor selected to copy an object of R, or
- [(17.3)](#promise-17.3)
for the second version, any exception thrown by the constructor selected to move an object of R[.](#promise-17.sentence-1)
[18](#promise-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11608)
*Error conditions*:
- [(18.1)](#promise-18.1)
promise_already_satisfied if its shared state
already has a stored value or exception[.](#promise-18.1.sentence-1)
- [(18.2)](#promise-18.2)
no_state if *this has no shared state[.](#promise-18.2.sentence-1)
[🔗](#lib:set_exception,promise)
`void set_exception(exception_ptr p);
`
[19](#promise-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11623)
*Preconditions*: p is not null[.](#promise-19.sentence-1)
[20](#promise-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11627)
*Effects*: Atomically stores the exception pointer p in the shared state
and makes that state ready ([[futures.state]](#state "32.10.5Shared state"))[.](#promise-20.sentence-1)
[21](#promise-21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11632)
*Throws*: future_error if its shared state
already has a stored value or exception[.](#promise-21.sentence-1)
[22](#promise-22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11637)
*Error conditions*:
- [(22.1)](#promise-22.1)
promise_already_satisfied if its shared state
already has a stored value or exception[.](#promise-22.1.sentence-1)
- [(22.2)](#promise-22.2)
no_state if *this has no shared state[.](#promise-22.2.sentence-1)
[🔗](#lib:set_value_at_thread_exit,promise)
`void promise::set_value_at_thread_exit(const R& r);
void promise::set_value_at_thread_exit(R&& r);
void promise<R&>::set_value_at_thread_exit(R& r);
void promise<void>::set_value_at_thread_exit();
`
[23](#promise-23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11655)
*Effects*: Stores the value r in the shared state without making that
state ready immediately[.](#promise-23.sentence-1)
Schedules that state to be made ready when the current
thread exits, after all objects with thread storage duration associated with the
current thread have been destroyed[.](#promise-23.sentence-2)
[24](#promise-24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11662)
*Throws*:
- [(24.1)](#promise-24.1)
future_error if its shared state
already has a stored value or exception, or
- [(24.2)](#promise-24.2)
for the first version, any exception thrown by the constructor selected to copy an object of R, or
- [(24.3)](#promise-24.3)
for the second version, any exception thrown by the constructor selected to move an object of R[.](#promise-24.sentence-1)
[25](#promise-25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11671)
*Error conditions*:
- [(25.1)](#promise-25.1)
promise_already_satisfied if its shared state
already has a stored value or exception[.](#promise-25.1.sentence-1)
- [(25.2)](#promise-25.2)
no_state if *this has no shared state[.](#promise-25.2.sentence-1)
[🔗](#lib:set_exception_at_thread_exit,promise)
`void set_exception_at_thread_exit(exception_ptr p);
`
[26](#promise-26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11686)
*Preconditions*: p is not null[.](#promise-26.sentence-1)
[27](#promise-27)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11690)
*Effects*: Stores the exception pointer p in the shared state without
making that state ready immediately[.](#promise-27.sentence-1)
Schedules that state to be made ready when
the current thread exits, after all objects with thread storage duration
associated with the current thread have been destroyed[.](#promise-27.sentence-2)
[28](#promise-28)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11697)
*Throws*: future_error if an error condition occurs[.](#promise-28.sentence-1)
[29](#promise-29)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11701)
*Error conditions*:
- [(29.1)](#promise-29.1)
promise_already_satisfied if its shared state
already has a stored value or exception[.](#promise-29.1.sentence-1)
- [(29.2)](#promise-29.2)
no_state if *this has no shared state[.](#promise-29.2.sentence-1)
[🔗](#lib:swap,promise_)
`template<class R>
void swap(promise<R>& x, promise<R>& y) noexcept;
`
[30](#promise-30)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11717)
*Effects*: As if by x.swap(y)[.](#promise-30.sentence-1)
### [32.10.7](#unique.future) Class template future [[futures.unique.future]](futures.unique.future)
[1](#unique.future-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11724)
The class template future defines a type for asynchronous return objects which
do not share their shared state with other asynchronous return objects[.](#unique.future-1.sentence-1)
A default-constructed future object has no
shared state[.](#unique.future-1.sentence-2)
A future object with shared state can be created by
functions on [asynchronous providers](#def:asynchronous_provider "32.10.5Shared state[futures.state]") or by the move constructor and shares its shared state with
the original asynchronous provider[.](#unique.future-1.sentence-3)
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[.](#unique.future-1.sentence-4)
[2](#unique.future-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11739)
[*Note [1](#unique.future-note-1)*:
Member functions of future do not synchronize with themselves or with
member functions of shared_future[.](#unique.future-2.sentence-1)
— *end note*]
[3](#unique.future-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11745)
The effect of calling any member function other than the destructor, the
move assignment operator, share, or valid on a future object for whichvalid() == false is undefined[.](#unique.future-3.sentence-1)
[*Note [2](#unique.future-note-2)*:
It is valid to move from a future object for which valid() == false[.](#unique.future-3.sentence-2)
— *end note*]
*Recommended practice*: Implementations should detect this case and throw an object of typefuture_error with an error condition of future_errc::no_state[.](#unique.future-3.sentence-3)
[🔗](#lib:future)
namespace std {template<class R>class future {public: future() noexcept;
future(future&&) noexcept;
future(const future&) = delete; ~future();
future& operator=(const future&) = delete;
future& operator=(future&&) noexcept;
shared_future<R> share() noexcept; // retrieving the value*see below* get(); // functions to check statebool 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; };}
[4](#unique.future-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11787)
For the primary template, R shall be an object type that
meets the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2Template argument requirements[utility.arg.requirements]") requirements[.](#unique.future-4.sentence-1)
[5](#unique.future-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11791)
The implementation provides the template future and two specializations,future<R&> and future<void>[.](#unique.future-5.sentence-1)
These differ only in the return type and return
value of the member function get, as set out in its description, below[.](#unique.future-5.sentence-2)
[🔗](#lib:future,constructor)
`future() noexcept;
`
[6](#unique.future-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11802)
*Effects*: The object does not refer to a shared state[.](#unique.future-6.sentence-1)
[7](#unique.future-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11806)
*Postconditions*: valid() == false[.](#unique.future-7.sentence-1)
[🔗](#lib:future,constructor_)
`future(future&& rhs) noexcept;
`
[8](#unique.future-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11817)
*Effects*: Move constructs a future object that refers to the shared
state that
was originally referred to by rhs (if any)[.](#unique.future-8.sentence-1)
[9](#unique.future-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11823)
*Postconditions*:
- [(9.1)](#unique.future-9.1)
valid() returns the same value as rhs.valid() prior to the
constructor invocation[.](#unique.future-9.1.sentence-1)
- [(9.2)](#unique.future-9.2)
rhs.valid() == false[.](#unique.future-9.2.sentence-1)
[🔗](#lib:future,constructor__)
`~future();
`
[10](#unique.future-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11838)
*Effects*:
- [(10.1)](#unique.future-10.1)
Releases any shared state ([[futures.state]](#state "32.10.5Shared state"));
- [(10.2)](#unique.future-10.2)
destroys *this[.](#unique.future-10.sentence-1)
[🔗](#lib:operator=,future)
`future& operator=(future&& rhs) noexcept;
`
[11](#unique.future-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11854)
*Effects*: If addressof(rhs) == this is true, there are no effects[.](#unique.future-11.sentence-1)
Otherwise:
- [(11.1)](#unique.future-11.1)
Releases any shared state ([[futures.state]](#state "32.10.5Shared state"))[.](#unique.future-11.1.sentence-1)
- [(11.2)](#unique.future-11.2)
move assigns the contents of rhs to *this[.](#unique.future-11.2.sentence-1)
[12](#unique.future-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11865)
*Postconditions*:
- [(12.1)](#unique.future-12.1)
valid() returns the same value as rhs.valid() prior to the
assignment[.](#unique.future-12.1.sentence-1)
- [(12.2)](#unique.future-12.2)
If addressof(rhs) == this is false,rhs.valid() == false[.](#unique.future-12.2.sentence-1)
[🔗](#lib:share,future)
`shared_future<R> share() noexcept;
`
[13](#unique.future-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11884)
*Postconditions*: valid() == false[.](#unique.future-13.sentence-1)
[14](#unique.future-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11888)
*Returns*: shared_future<R>(std::move(*this))[.](#unique.future-14.sentence-1)
[🔗](#lib:get,future)
`R future::get();
R& future<R&>::get();
void future<void>::get();
`
[15](#unique.future-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11901)
[*Note [3](#unique.future-note-3)*:
As described above, the template and its two required specializations differ only in
the return type and return value of the member function get[.](#unique.future-15.sentence-1)
— *end note*]
[16](#unique.future-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11907)
*Effects*:
- [(16.1)](#unique.future-16.1)
wait()s until the shared state is ready, then retrieves the
value stored in the shared state;
- [(16.2)](#unique.future-16.2)
releases any shared state ([[futures.state]](#state "32.10.5Shared state"))[.](#unique.future-16.sentence-1)
[17](#unique.future-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11915)
*Postconditions*: valid() == false[.](#unique.future-17.sentence-1)
[18](#unique.future-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11919)
*Returns*:
- [(18.1)](#unique.future-18.1)
future::get() returns the value v stored in the object's shared state asstd::move(v)[.](#unique.future-18.1.sentence-1)
- [(18.2)](#unique.future-18.2)
future<R&>::get() returns the reference stored as value in the object's shared state[.](#unique.future-18.2.sentence-1)
- [(18.3)](#unique.future-18.3)
future<void>::get() returns nothing[.](#unique.future-18.3.sentence-1)
[19](#unique.future-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11933)
*Throws*: The stored exception, if an exception was stored in the shared state[.](#unique.future-19.sentence-1)
[🔗](#lib:valid,future)
`bool valid() const noexcept;
`
[20](#unique.future-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11944)
*Returns*: true only if *this refers to a shared state[.](#unique.future-20.sentence-1)
[🔗](#lib:wait,future)
`void wait() const;
`
[21](#unique.future-21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11955)
*Effects*: Blocks until the shared state is ready[.](#unique.future-21.sentence-1)
[🔗](#lib:wait_for,future)
`template<class Rep, class Period>
future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
`
[22](#unique.future-22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11968)
*Effects*: None if the shared state contains a deferred function ([[futures.async]](#async "32.10.9Function template async")),
otherwise
blocks until the shared state is ready or until
the relative timeout ([[thread.req.timing]](thread.req.timing "32.2.4Timing specifications")) specified by rel_time has expired[.](#unique.future-22.sentence-1)
[23](#unique.future-23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11976)
*Returns*:
- [(23.1)](#unique.future-23.1)
future_status::deferred if the shared state contains a deferred
function[.](#unique.future-23.1.sentence-1)
- [(23.2)](#unique.future-23.2)
future_status::ready if the shared state is ready[.](#unique.future-23.2.sentence-1)
- [(23.3)](#unique.future-23.3)
future_status::timeout if the function is returning because the
relative timeout ([[thread.req.timing]](thread.req.timing "32.2.4Timing specifications"))
specified by rel_time has expired[.](#unique.future-23.3.sentence-1)
[24](#unique.future-24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11989)
*Throws*: timeout-related exceptions ([[thread.req.timing]](thread.req.timing "32.2.4Timing specifications"))[.](#unique.future-24.sentence-1)
[🔗](#lib:wait_until,future)
`template<class Clock, class Duration>
future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
`
[25](#unique.future-25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12001)
*Effects*: None if the shared state contains a deferred function ([[futures.async]](#async "32.10.9Function template async")),
otherwise
blocks until the shared state is ready or until
the absolute timeout ([[thread.req.timing]](thread.req.timing "32.2.4Timing specifications")) specified by abs_time has expired[.](#unique.future-25.sentence-1)
[26](#unique.future-26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12009)
*Returns*:
- [(26.1)](#unique.future-26.1)
future_status::deferred if the shared state contains a deferred
function[.](#unique.future-26.1.sentence-1)
- [(26.2)](#unique.future-26.2)
future_status::ready if the shared state is ready[.](#unique.future-26.2.sentence-1)
- [(26.3)](#unique.future-26.3)
future_status::timeout if the function is returning because the
absolute timeout ([[thread.req.timing]](thread.req.timing "32.2.4Timing specifications"))
specified by abs_time has expired[.](#unique.future-26.3.sentence-1)
[27](#unique.future-27)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12023)
*Throws*: timeout-related exceptions ([[thread.req.timing]](thread.req.timing "32.2.4Timing specifications"))[.](#unique.future-27.sentence-1)
### [32.10.8](#shared.future) Class template shared_future [[futures.shared.future]](futures.shared.future)
[1](#shared.future-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12031)
The class template shared_future defines a type for asynchronous return objects
which may share their shared state with other asynchronous return
objects[.](#shared.future-1.sentence-1)
A default-constructed shared_future object has no shared state[.](#shared.future-1.sentence-2)
A shared_future object with
shared state can
be created
by conversion from a future object and shares its shared state with the
original [asynchronous provider](#def:asynchronous_provider "32.10.5Shared state[futures.state]") of the shared state[.](#shared.future-1.sentence-3)
The result (value or exception) of a shared_future object
can be set by
calling a respective function on an
object that shares the same shared state[.](#shared.future-1.sentence-4)
[2](#shared.future-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12045)
[*Note [1](#shared.future-note-1)*:
Member functions of shared_future do not synchronize with themselves,
but they synchronize with the shared state[.](#shared.future-2.sentence-1)
— *end note*]
[3](#shared.future-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12051)
The effect of calling any member function other than the destructor,
the move assignment operator, the copy assignment operator, orvalid() on a shared_future object for which valid() == false is undefined[.](#shared.future-3.sentence-1)
[*Note [2](#shared.future-note-2)*:
It is valid to copy or move from a shared_future object for which valid() is false[.](#shared.future-3.sentence-2)
— *end note*]
*Recommended practice*: Implementations should detect this case and throw an object of typefuture_error with an error condition of future_errc::no_state[.](#shared.future-3.sentence-3)
[🔗](#lib:shared_future)
namespace std {template<class R>class shared_future {public: shared_future() noexcept;
shared_future(const shared_future& rhs) noexcept;
shared_future(future<R>&&) noexcept;
shared_future(shared_future&& rhs) noexcept; ~shared_future();
shared_future& operator=(const shared_future& rhs) noexcept;
shared_future& operator=(shared_future&& rhs) noexcept; // retrieving the value*see below* get() const; // functions to check statebool 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; };}
[4](#shared.future-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12093)
For the primary template, R shall be an object type that
meets the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2Template argument requirements[utility.arg.requirements]") requirements[.](#shared.future-4.sentence-1)
[5](#shared.future-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12097)
The implementation provides the template shared_future and two
specializations, shared_future<R&> and shared_future<void>[.](#shared.future-5.sentence-1)
These
differ only in the return type and return value of the member function get, as
set out in its description, below[.](#shared.future-5.sentence-2)
[🔗](#lib:shared_future,constructor)
`shared_future() noexcept;
`
[6](#shared.future-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12109)
*Effects*: The object does not refer to a shared state[.](#shared.future-6.sentence-1)
[7](#shared.future-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12113)
*Postconditions*: valid() == false[.](#shared.future-7.sentence-1)
[🔗](#lib:shared_future,constructor_)
`shared_future(const shared_future& rhs) noexcept;
`
[8](#shared.future-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12124)
*Effects*: The object refers to the same
shared state as rhs (if any)[.](#shared.future-8.sentence-1)
[9](#shared.future-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12129)
*Postconditions*: valid() returns the same value as rhs.valid()[.](#shared.future-9.sentence-1)
[🔗](#lib:shared_future,constructor__)
`shared_future(future<R>&& rhs) noexcept;
shared_future(shared_future&& rhs) noexcept;
`
[10](#shared.future-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12141)
*Effects*: Move constructs a shared_future object that refers to the
shared state that was originally referred to by rhs (if any)[.](#shared.future-10.sentence-1)
[11](#shared.future-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12146)
*Postconditions*:
- [(11.1)](#shared.future-11.1)
valid() returns the same value as rhs.valid() returned prior to
the constructor invocation[.](#shared.future-11.1.sentence-1)
- [(11.2)](#shared.future-11.2)
rhs.valid() == false[.](#shared.future-11.2.sentence-1)
[🔗](#lib:shared_future,destructor)
`~shared_future();
`
[12](#shared.future-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12161)
*Effects*:
- [(12.1)](#shared.future-12.1)
Releases any shared state ([[futures.state]](#state "32.10.5Shared state"));
- [(12.2)](#shared.future-12.2)
destroys *this[.](#shared.future-12.sentence-1)
[🔗](#lib:operator=,shared_future)
`shared_future& operator=(shared_future&& rhs) noexcept;
`
[13](#shared.future-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12177)
*Effects*: If addressof(rhs) == this is true, there are no effects[.](#shared.future-13.sentence-1)
Otherwise:
- [(13.1)](#shared.future-13.1)
Releases any shared state ([[futures.state]](#state "32.10.5Shared state"));
- [(13.2)](#shared.future-13.2)
move assigns the contents of rhs to *this[.](#shared.future-13.sentence-2)
[14](#shared.future-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12188)
*Postconditions*:
- [(14.1)](#shared.future-14.1)
valid() returns the same value as rhs.valid() returned prior to
the assignment[.](#shared.future-14.1.sentence-1)
- [(14.2)](#shared.future-14.2)
If addressof(rhs) == this is false,rhs.valid() == false[.](#shared.future-14.2.sentence-1)
[🔗](#lib:operator=,shared_future_)
`shared_future& operator=(const shared_future& rhs) noexcept;
`
[15](#shared.future-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12207)
*Effects*: If addressof(rhs) == this is true, there are no effects[.](#shared.future-15.sentence-1)
Otherwise:
- [(15.1)](#shared.future-15.1)
Releases any shared state ([[futures.state]](#state "32.10.5Shared state"));
- [(15.2)](#shared.future-15.2)
assigns the contents of rhs to *this[.](#shared.future-15.sentence-2)
[*Note [3](#shared.future-note-3)*:
As a result,*this refers to the same shared state as rhs (if any)[.](#shared.future-15.2.sentence-2)
— *end note*]
[16](#shared.future-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12223)
*Postconditions*: valid() == rhs.valid()[.](#shared.future-16.sentence-1)
[🔗](#lib:get,shared_future)
`const R& shared_future::get() const;
R& shared_future<R&>::get() const;
void shared_future<void>::get() const;
`
[17](#shared.future-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12236)
[*Note [4](#shared.future-note-4)*:
As described above, the template and its two required specializations differ only in
the return type and return value of the member function get[.](#shared.future-17.sentence-1)
— *end note*]
[18](#shared.future-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12242)
[*Note [5](#shared.future-note-5)*:
Access to a value object stored in the shared state is
unsynchronized, so operations on R might
introduce a data race ([[intro.multithread]](intro.multithread "6.10.2Multi-threaded executions and data races"))[.](#shared.future-18.sentence-1)
— *end note*]
[19](#shared.future-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12249)
*Effects*: wait()s until the shared state is ready, then retrieves the
value stored in the shared state[.](#shared.future-19.sentence-1)
[20](#shared.future-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12254)
*Returns*:
- [(20.1)](#shared.future-20.1)
shared_future::get() returns a const reference to the value stored in the object's
shared state[.](#shared.future-20.1.sentence-1)
[*Note [6](#shared.future-note-6)*:
Access through that reference after the shared state has been
destroyed produces undefined behavior; this can be avoided by not storing the reference in any
storage with a greater lifetime than the shared_future object that returned the
reference[.](#shared.future-20.1.sentence-2)
— *end note*]
- [(20.2)](#shared.future-20.2)
shared_future<R&>::get() returns the reference stored as value in the object's
shared state[.](#shared.future-20.2.sentence-1)
- [(20.3)](#shared.future-20.3)
shared_future<void>::get() returns nothing[.](#shared.future-20.3.sentence-1)
[21](#shared.future-21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12275)
*Throws*: The stored exception, if an exception was stored in the shared state[.](#shared.future-21.sentence-1)
[🔗](#lib:valid,shared_future)
`bool valid() const noexcept;
`
[22](#shared.future-22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12286)
*Returns*: true only if *this refers to a shared state[.](#shared.future-22.sentence-1)
[🔗](#lib:wait,shared_future)
`void wait() const;
`
[23](#shared.future-23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12297)
*Effects*: Blocks until the shared state is ready[.](#shared.future-23.sentence-1)
[🔗](#lib:wait_for,shared_future)
`template<class Rep, class Period>
future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
`
[24](#shared.future-24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12310)
*Effects*: None if the shared state contains a deferred function ([[futures.async]](#async "32.10.9Function template async")),
otherwise
blocks until the shared state is ready or until
the relative timeout ([[thread.req.timing]](thread.req.timing "32.2.4Timing specifications")) specified byrel_time has expired[.](#shared.future-24.sentence-1)
[25](#shared.future-25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12319)
*Returns*:
- [(25.1)](#shared.future-25.1)
future_status::deferred if the shared state contains a deferred
function[.](#shared.future-25.1.sentence-1)
- [(25.2)](#shared.future-25.2)
future_status::ready if the shared state is ready[.](#shared.future-25.2.sentence-1)
- [(25.3)](#shared.future-25.3)
future_status::timeout if the function is returning because the
relative timeout ([[thread.req.timing]](thread.req.timing "32.2.4Timing specifications"))
specified by rel_time has expired[.](#shared.future-25.3.sentence-1)
[26](#shared.future-26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12332)
*Throws*: timeout-related exceptions ([[thread.req.timing]](thread.req.timing "32.2.4Timing specifications"))[.](#shared.future-26.sentence-1)
[🔗](#lib:wait_until,shared_future)
`template<class Clock, class Duration>
future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
`
[27](#shared.future-27)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12344)
*Effects*: None if the shared state contains a deferred function ([[futures.async]](#async "32.10.9Function template async")),
otherwise
blocks until the shared state is ready or until the
absolute timeout ([[thread.req.timing]](thread.req.timing "32.2.4Timing specifications")) specified byabs_time has expired[.](#shared.future-27.sentence-1)
[28](#shared.future-28)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12353)
*Returns*:
- [(28.1)](#shared.future-28.1)
future_status::deferred if the shared state contains a deferred
function[.](#shared.future-28.1.sentence-1)
- [(28.2)](#shared.future-28.2)
future_status::ready if the shared state is ready[.](#shared.future-28.2.sentence-1)
- [(28.3)](#shared.future-28.3)
future_status::timeout if the function is returning because the
absolute timeout ([[thread.req.timing]](thread.req.timing "32.2.4Timing specifications"))
specified by abs_time has expired[.](#shared.future-28.3.sentence-1)
[29](#shared.future-29)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12366)
*Throws*: timeout-related exceptions ([[thread.req.timing]](thread.req.timing "32.2.4Timing specifications"))[.](#shared.future-29.sentence-1)
### [32.10.9](#async) Function template async [[futures.async]](futures.async)
[1](#async-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12373)
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[.](#async-1.sentence-1)
[🔗](#lib:async)
`template<class F, class... Args>
future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
async(F&& f, Args&&... args);
template<class F, class... Args>
future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
async(launch policy, F&& f, Args&&... args);
`
[2](#async-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12389)
*Mandates*: The following are all true:
- [(2.1)](#async-2.1)
is_constructible_v<decay_t<F>, F>,
- [(2.2)](#async-2.2)
(is_constructible_v<decay_t<Args>, Args> && ...), and
- [(2.3)](#async-2.3)
is_invocable_v<decay_t<F>, decay_t<Args>...>[.](#async-2.sentence-1)
[3](#async-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12398)
*Effects*: The first function
behaves the same as a call to the second function with a policy argument oflaunch::async | launch::deferred and the same arguments for F and Args[.](#async-3.sentence-1)
The second function creates a shared state that is associated with
the returned future object[.](#async-3.sentence-2)
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):
- [(3.1)](#async-3.1)
If launch::async is set in policy, callsinvoke(auto(std::forward<F>(f)), auto(std::forward<Args>(args))...) ([[func.invoke]](func.invoke "22.10.5invoke functions"), [[thread.thread.constr]](thread.thread.constr "32.4.3.3Constructors"))
as if in a new thread of execution represented by a thread object
with the values produced by auto being materialized ([[conv.rval]](conv.rval "7.3.5Temporary materialization conversion")) in the thread that called async[.](#async-3.1.sentence-1)
Any return value
is stored as the result in the
shared state[.](#async-3.1.sentence-2)
Any exception propagated from
the execution ofinvoke(auto(std::forward<F>(f)), auto(std::forward<Args>(args))...) is stored as the exceptional result in the shared state[.](#async-3.1.sentence-3)
The thread object is
stored in the shared state
and affects the behavior of any asynchronous return objects that
reference that state[.](#async-3.1.sentence-4)
- [(3.2)](#async-3.2)
If launch::deferred is set in policy,
stores auto(std::forward<F>(f)) andauto(std::forward<Args>(args))... in the shared state[.](#async-3.2.sentence-1)
These copies of f and args constitute
a [*deferred function*](#def:function,deferred "32.10.9Function template async[futures.async]")[.](#async-3.2.sentence-2)
Invocation of the deferred function evaluatesinvoke(std::move(g), std::move(xyz)) where g is the stored value ofauto(std::forward<F>(f)) and xyz is the stored copy ofauto(std::forward<Args>(args))...[.](#async-3.2.sentence-3)
Any return value is stored
as the result in the shared state[.](#async-3.2.sentence-4)
Any exception propagated
from the execution
of the deferred function
is stored as the exceptional result
in the shared state[.](#async-3.2.sentence-5)
The shared state is not
made ready until the function has completed[.](#async-3.2.sentence-6)
The first call to a
non-timed waiting function ([[futures.state]](#state "32.10.5Shared state"))
on an asynchronous return object referring to
this shared state invokes the
deferred function in the thread that called the waiting function[.](#async-3.2.sentence-7)
Once evaluation of invoke(std::move(g), std::move(xyz)) begins, the function is no longer
considered deferred[.](#async-3.2.sentence-8)
*Recommended practice*: If this policy is specified together with other policies, such as when using apolicy value of launch::async | launch::deferred, implementations should defer
invocation or the selection of the policy when no more concurrency can be effectively
exploited[.](#async-3.2.sentence-9)
- [(3.3)](#async-3.3)
If no value is set in the launch policy, or a value is set that is neither specified
in this document nor by the implementation, the behavior is undefined[.](#async-3.3.sentence-1)
[4](#async-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12464)
*Synchronization*: The invocation of async synchronizes with the invocation of f[.](#async-4.sentence-1)
The completion of the function f is sequenced before
the shared state is made ready[.](#async-4.sentence-2)
[*Note [1](#async-note-1)*:
These apply regardless of the provided policy argument, and
even if the corresponding future object is moved to another thread[.](#async-4.sentence-3)
However, it is possible for f not to be called at all,
in which case its completion never happens[.](#async-4.sentence-4)
— *end note*]
If the implementation chooses the launch::async policy,
- [(4.1)](#async-4.1)
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 ([[thread.thread.member]](thread.thread.member "32.4.3.6Members"));
- [(4.2)](#async-4.2)
the associated thread completion[synchronizes with](intro.multithread#def:synchronize_with "6.10.2Multi-threaded executions and data races[intro.multithread]") 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[.](#async-4.sentence-5)
[5](#async-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12494)
*Returns*: An object of typefuture<invoke_result_t<decay_t<F>, decay_t<Args>...>> that refers
to the shared state created by this call to async[.](#async-5.sentence-1)
[*Note [2](#async-note-2)*:
If a future obtained from async is moved outside the local scope,
the future's destructor can block for the shared state to become ready[.](#async-5.sentence-2)
— *end note*]
[6](#async-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12504)
*Throws*: system_error if policy == launch::async and the
implementation is unable to start a new thread, orstd::bad_alloc if memory for the internal data structures
cannot be allocated[.](#async-6.sentence-1)
[7](#async-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12511)
*Error conditions*:
- [(7.1)](#async-7.1)
resource_unavailable_try_again — ifpolicy == launch::async and the system is unable to start a new thread[.](#async-7.sentence-1)
[8](#async-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12519)
[*Example [1](#async-example-1)*: int work1(int value);int work2(int value);int work(int value) {auto handle = std::async([=]{ return work2(value); }); int tmp = work1(value); return tmp + handle.get(); // #1}
[*Note [3](#async-note-3)*:
Line #1 might not result in concurrency because
the async call uses the default policy, which might uselaunch::deferred, in which case the lambda might not be invoked until theget() call; in that case, work1 and work2 are called on the
same thread and there is no concurrency[.](#async-8.sentence-1)
— *end note*]
— *end example*]
### [32.10.10](#task) Class template packaged_task [[futures.task]](futures.task)
#### [32.10.10.1](#task.general) General [[futures.task.general]](futures.task.general)
[1](#task.general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12544)
The class template packaged_task defines a type for wrapping a function or
callable object so that the return value of the function or callable object is stored in
a future when it is invoked[.](#task.general-1.sentence-1)
[2](#task.general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12549)
When the packaged_task object is invoked, its stored task is invoked and the
result (whether normal or exceptional) stored in the shared state[.](#task.general-2.sentence-1)
Any futures that
share the shared state will then be able to access the stored result[.](#task.general-2.sentence-2)
[🔗](#lib:packaged_task)
namespace std {template<class> class packaged_task; // *not defined*template<class R, class... ArgTypes>class packaged_task<R(ArgTypes...)> {public:// construction and destruction packaged_task() noexcept; template<class F>explicit packaged_task(F&& f); template<class F, class Allocator>explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f); ~packaged_task(); // no copy packaged_task(const packaged_task&) = delete;
packaged_task& operator=(const packaged_task&) = delete; // move support packaged_task(packaged_task&& rhs) noexcept;
packaged_task& operator=(packaged_task&& rhs) noexcept; void swap(packaged_task& other) noexcept; bool valid() const noexcept; // result retrieval future<R> get_future(); // executionvoid operator()(ArgTypes... ); void make_ready_at_thread_exit(ArgTypes...); void reset(); }; template<class R, class... ArgTypes> packaged_task(R (*)(ArgTypes...)) -> packaged_task<R(ArgTypes...)>; template<class F> packaged_task(F) -> packaged_task<*see below*>;}
#### [32.10.10.2](#task.members) Member functions [[futures.task.members]](futures.task.members)
[🔗](#lib:packaged_task,constructor)
`packaged_task() noexcept;
`
[1](#task.members-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12606)
*Effects*: The object has no shared state and no stored task[.](#task.members-1.sentence-1)
[🔗](#lib:packaged_task,constructor_)
`template<class F>
explicit packaged_task(F&& f);
`
[2](#task.members-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12618)
*Effects*: Equivalent topackaged_task(allocator_arg, allocator<int>(), std::forward<F>(f))[.](#task.members-2.sentence-1)
[🔗](#lib:packaged_task,constructor__)
`template<class F, class Allocator>
explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
`
[3](#task.members-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12631)
*Constraints*: remove_cvref_t<F> is not the same type as packaged_task<R(ArgTypes...)>[.](#task.members-3.sentence-1)
[4](#task.members-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12636)
*Mandates*: is_invocable_r_v<R, decay_t<F>&, ArgTypes...> is true[.](#task.members-4.sentence-1)
[5](#task.members-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12640)
*Preconditions*: Allocator meets the *Cpp17Allocator* requirements ([[allocator.requirements.general]](allocator.requirements.general "16.4.4.6.1General"))[.](#task.members-5.sentence-1)
[6](#task.members-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12644)
*Effects*: Let A2 beallocator_traits<Allocator>::rebind_alloc<*unspecified*> and let a2 be an object of type A2 initialized withA2(a)[.](#task.members-6.sentence-1)
Constructs a new packaged_task object with
a stored task of type decay_t<F> and a shared state[.](#task.members-6.sentence-2)
Initializes the object's stored task with std::forward<F>(f)[.](#task.members-6.sentence-3)
Uses a2 to allocate storage for the shared state and stores a copy
of a2 in the shared state[.](#task.members-6.sentence-4)
[7](#task.members-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12656)
*Throws*: Any exceptions thrown by the initialization of the stored task[.](#task.members-7.sentence-1)
If storage for the shared state cannot be allocated, any exception thrown byA2::allocate[.](#task.members-7.sentence-2)
[🔗](#lib:packaged_task,constructor___)
`template<class F> packaged_task(F) -> packaged_task<see below>;
`
[8](#task.members-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12669)
*Constraints*: &F::operator() is well-formed when
treated as an unevaluated operand ([[expr.context]](expr.context#term.unevaluated.operand "7.2.3Context dependence")) and either
- [(8.1)](#task.members-8.1)
F::operator() is a non-static member function anddecltype(&F::operator()) is either of the formR(G::*)(A...) cv &opt noexceptopt or of the formR(*)(G, A...) noexceptopt for a type G, or
- [(8.2)](#task.members-8.2)
F::operator() is a static member function anddecltype(&F::operator()) is of the formR(*)(A...) noexceptopt[.](#task.members-8.sentence-1)
[9](#task.members-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12687)
*Remarks*: The deduced type is packaged_task<R(A...)>[.](#task.members-9.sentence-1)
[🔗](#lib:packaged_task,constructor____)
`packaged_task(packaged_task&& rhs) noexcept;
`
[10](#task.members-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12698)
*Effects*: Transfers ownership ofrhs's shared state to *this, leaving rhs with no
shared state[.](#task.members-10.sentence-1)
Moves the stored task from rhs to *this[.](#task.members-10.sentence-2)
[11](#task.members-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12704)
*Postconditions*: rhs has no shared state[.](#task.members-11.sentence-1)
[🔗](#lib:operator=,packaged_task)
`packaged_task& operator=(packaged_task&& rhs) noexcept;
`
[12](#task.members-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12715)
*Effects*:
- [(12.1)](#task.members-12.1)
Releases any shared state ([[futures.state]](#state "32.10.5Shared state"));
- [(12.2)](#task.members-12.2)
calls packaged_task(std::move(rhs)).swap(*this)[.](#task.members-12.sentence-1)
[🔗](#lib:packaged_task,destructor)
`~packaged_task();
`
[13](#task.members-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12731)
*Effects*: Abandons any shared state ([[futures.state]](#state "32.10.5Shared state"))[.](#task.members-13.sentence-1)
[🔗](#lib:swap,packaged_task)
`void swap(packaged_task& other) noexcept;
`
[14](#task.members-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12742)
*Effects*: Exchanges the shared states and stored tasks of *this and other[.](#task.members-14.sentence-1)
[15](#task.members-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12746)
*Postconditions*: *this has the same shared state
and stored task (if any) as other prior to the call to swap[.](#task.members-15.sentence-1)
other has the same shared state
and stored task (if any)
as *this prior to the call to swap[.](#task.members-15.sentence-2)
[🔗](#lib:valid,packaged_task)
`bool valid() const noexcept;
`
[16](#task.members-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12761)
*Returns*: true only if *this has a shared state[.](#task.members-16.sentence-1)
[🔗](#lib:get_future,packaged_task)
`future<R> get_future();
`
[17](#task.members-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12772)
*Synchronization*: Calls to this function do not introduce
data races ([[intro.multithread]](intro.multithread "6.10.2Multi-threaded executions and data races")) with calls tooperator() ormake_ready_at_thread_exit[.](#task.members-17.sentence-1)
[*Note [1](#task.members-note-1)*:
Such calls need not synchronize with each other[.](#task.members-17.sentence-2)
— *end note*]
[18](#task.members-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12782)
*Returns*: A future object that shares the same shared state as *this[.](#task.members-18.sentence-1)
[19](#task.members-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12786)
*Throws*: A future_error object if an error occurs[.](#task.members-19.sentence-1)
[20](#task.members-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12790)
*Error conditions*:
- [(20.1)](#task.members-20.1)
future_already_retrieved if get_future has already been called on
a packaged_task object with the same shared state as *this[.](#task.members-20.1.sentence-1)
- [(20.2)](#task.members-20.2)
no_state if *this has no shared state[.](#task.members-20.2.sentence-1)
[🔗](#lib:operator(),packaged_task)
`void operator()(ArgTypes... args);
`
[21](#task.members-21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12805)
*Effects*: As if by *INVOKE*<R>(f, t1, t2, …, tN) ([[func.require]](func.require "22.10.4Requirements")),
where f is the
stored task of *this andt1, t2, …, tN are the values in args...[.](#task.members-21.sentence-1)
If the task returns normally,
the return value is stored as the asynchronous result in the shared state of*this, otherwise the exception thrown by the task is stored[.](#task.members-21.sentence-2)
The
shared state of *this is made ready, and any threads blocked in a
function waiting for
the shared state of *this to become ready are unblocked[.](#task.members-21.sentence-3)
[22](#task.members-22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12817)
*Throws*: A future_error exception object if there is no shared
state or the stored task has already been invoked[.](#task.members-22.sentence-1)
[23](#task.members-23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12822)
*Error conditions*:
- [(23.1)](#task.members-23.1)
promise_already_satisfied if
the stored task has already been invoked[.](#task.members-23.1.sentence-1)
- [(23.2)](#task.members-23.2)
no_state if *this has no shared state[.](#task.members-23.2.sentence-1)
[🔗](#lib:make_ready_at_thread_exit,packaged_task)
`void make_ready_at_thread_exit(ArgTypes... args);
`
[24](#task.members-24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12837)
*Effects*: As if by *INVOKE*<R>(f, t1, t2, …, tN) ([[func.require]](func.require "22.10.4Requirements")),
where f is the stored task andt1, t2, …, tN are the values in args...[.](#task.members-24.sentence-1)
If the task returns normally,
the return value is stored as the asynchronous result in the shared state of*this, otherwise the exception thrown by the task is stored[.](#task.members-24.sentence-2)
In either
case, this is done without making that state ready ([[futures.state]](#state "32.10.5Shared state")) immediately[.](#task.members-24.sentence-3)
Schedules
the shared state to be made ready when the current thread exits,
after all objects with thread storage duration associated with the current thread
have been destroyed[.](#task.members-24.sentence-4)
[25](#task.members-25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12849)
*Throws*: future_error if an error condition occurs[.](#task.members-25.sentence-1)
[26](#task.members-26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12853)
*Error conditions*:
- [(26.1)](#task.members-26.1)
promise_already_satisfied if the
stored task has already been invoked[.](#task.members-26.1.sentence-1)
- [(26.2)](#task.members-26.2)
no_state if *this has no shared state[.](#task.members-26.2.sentence-1)
[🔗](#lib:reset,packaged_task)
`void reset();
`
[27](#task.members-27)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12868)
*Effects*: Equivalent to:if (!valid()) {throw future_error(future_errc::no_state);}*this = packaged_task(allocator_arg, a, std::move(f)); wheref is the task stored in*this and a is the allocator stored in the shared state[.](#task.members-27.sentence-1)
[*Note [2](#task.members-note-2)*:
This constructs a new shared state for *this[.](#task.members-27.sentence-2)
The
old state is abandoned ([[futures.state]](#state "32.10.5Shared state"))[.](#task.members-27.sentence-3)
— *end note*]
[28](#task.members-28)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12885)
*Throws*:
- [(28.1)](#task.members-28.1)
Any exception thrown by the packaged_task constructor[.](#task.members-28.1.sentence-1)
- [(28.2)](#task.members-28.2)
future_error with an error condition of no_state if *this has no shared state[.](#task.members-28.2.sentence-1)
#### [32.10.10.3](#task.nonmembers) Globals [[futures.task.nonmembers]](futures.task.nonmembers)
[🔗](#lib:swap,packaged_task_)
`template<class R, class... ArgTypes>
void swap(packaged_task<R(ArgTypes...)>& x, packaged_task<R(ArgTypes...)>& y) noexcept;
`
[1](#task.nonmembers-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12903)
*Effects*: As if by x.swap(y)[.](#task.nonmembers-1.sentence-1)