Init
This commit is contained in:
366
cppdraft/futures/promise.md
Normal file
366
cppdraft/futures/promise.md
Normal 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.2 Template 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.5 Shared 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.5 Shared 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.2 Multi-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.5 Shared 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.5 Shared 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)
|
||||
Reference in New Issue
Block a user