This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

366
cppdraft/futures/promise.md Normal file
View File

@@ -0,0 +1,366 @@
[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)