Files
2025-10-25 03:02:53 +03:00

367 lines
11 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.promise]
# 32 Concurrency support library [[thread]](./#thread)
## 32.10 Futures [[futures]](futures#promise)
### 32.10.6 Class template 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](#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[.](#1.sentence-1)
[2](#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>[.](#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[.](#2.sentence-2)
[3](#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[.](#3.sentence-1)
[🔗](#lib:promise,constructor)
`promise();
template<class Allocator>
promise(allocator_arg_t, const Allocator& a);
`
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11479)
*Effects*: Creates a shared state[.](#4.sentence-1)
The second
constructor uses the allocator a to allocate memory for the shared
state[.](#4.sentence-2)
[🔗](#lib:promise,constructor_)
`promise(promise&& rhs) noexcept;
`
[5](#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[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11497)
*Postconditions*: rhs has no shared state[.](#6.sentence-1)
[🔗](#lib:promise,destructor)
`~promise();
`
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11508)
*Effects*: Abandons any shared state ([[futures.state]](futures.state "32.10.5Shared state"))[.](#7.sentence-1)
[🔗](#lib:operator=,promise)
`promise& operator=(promise&& rhs) noexcept;
`
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11519)
*Effects*: Abandons any shared state ([[futures.state]](futures.state "32.10.5Shared state")) and then as ifpromise(std::move(rhs)).swap(*this)[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11524)
*Returns*: *this[.](#9.sentence-1)
[🔗](#lib:swap,promise)
`void swap(promise& other) noexcept;
`
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11535)
*Effects*: Exchanges the shared state of *this and other[.](#10.sentence-1)
[11](#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[.](#11.sentence-1)
other has the shared state (if any) that*this had prior to the call to swap[.](#11.sentence-2)
[🔗](#lib:get_future,promise)
`future<R> get_future();
`
[12](#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[.](#12.sentence-1)
[*Note [1](#note-1)*:
Such calls need not synchronize with each other[.](#12.sentence-2)
— *end note*]
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11564)
*Returns*: A future<R> object with the same shared state as*this[.](#13.sentence-1)
[14](#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[.](#14.sentence-1)
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11575)
*Error conditions*:
- [(15.1)](#15.1)
future_already_retrieved if get_future has already been called on
a promise with the same shared state as *this[.](#15.1.sentence-1)
- [(15.2)](#15.2)
no_state if *this has no shared state[.](#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](#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]](futures.state "32.10.5Shared state"))[.](#16.sentence-1)
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11599)
*Throws*:
- [(17.1)](#17.1)
future_error if its shared state
already has a stored value or exception, or
- [(17.2)](#17.2)
for the first version, any exception thrown by the constructor selected to copy an object of R, or
- [(17.3)](#17.3)
for the second version, any exception thrown by the constructor selected to move an object of R[.](#17.sentence-1)
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11608)
*Error conditions*:
- [(18.1)](#18.1)
promise_already_satisfied if its shared state
already has a stored value or exception[.](#18.1.sentence-1)
- [(18.2)](#18.2)
no_state if *this has no shared state[.](#18.2.sentence-1)
[🔗](#lib:set_exception,promise)
`void set_exception(exception_ptr p);
`
[19](#19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11623)
*Preconditions*: p is not null[.](#19.sentence-1)
[20](#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]](futures.state "32.10.5Shared state"))[.](#20.sentence-1)
[21](#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[.](#21.sentence-1)
[22](#22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11637)
*Error conditions*:
- [(22.1)](#22.1)
promise_already_satisfied if its shared state
already has a stored value or exception[.](#22.1.sentence-1)
- [(22.2)](#22.2)
no_state if *this has no shared state[.](#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](#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[.](#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[.](#23.sentence-2)
[24](#24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11662)
*Throws*:
- [(24.1)](#24.1)
future_error if its shared state
already has a stored value or exception, or
- [(24.2)](#24.2)
for the first version, any exception thrown by the constructor selected to copy an object of R, or
- [(24.3)](#24.3)
for the second version, any exception thrown by the constructor selected to move an object of R[.](#24.sentence-1)
[25](#25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11671)
*Error conditions*:
- [(25.1)](#25.1)
promise_already_satisfied if its shared state
already has a stored value or exception[.](#25.1.sentence-1)
- [(25.2)](#25.2)
no_state if *this has no shared state[.](#25.2.sentence-1)
[🔗](#lib:set_exception_at_thread_exit,promise)
`void set_exception_at_thread_exit(exception_ptr p);
`
[26](#26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11686)
*Preconditions*: p is not null[.](#26.sentence-1)
[27](#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[.](#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[.](#27.sentence-2)
[28](#28)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11697)
*Throws*: future_error if an error condition occurs[.](#28.sentence-1)
[29](#29)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11701)
*Error conditions*:
- [(29.1)](#29.1)
promise_already_satisfied if its shared state
already has a stored value or exception[.](#29.1.sentence-1)
- [(29.2)](#29.2)
no_state if *this has no shared state[.](#29.2.sentence-1)
[🔗](#lib:swap,promise_)
`template<class R>
void swap(promise<R>& x, promise<R>& y) noexcept;
`
[30](#30)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11717)
*Effects*: As if by x.swap(y)[.](#30.sentence-1)