367 lines
11 KiB
Markdown
367 lines
11 KiB
Markdown
[futures.unique.future]
|
||
|
||
# 32 Concurrency support library [[thread]](./#thread)
|
||
|
||
## 32.10 Futures [[futures]](futures#unique.future)
|
||
|
||
### 32.10.7 Class template future [futures.unique.future]
|
||
|
||
[1](#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[.](#1.sentence-1)
|
||
|
||
A default-constructed future object has no
|
||
shared state[.](#1.sentence-2)
|
||
|
||
A future object with shared state can be created by
|
||
functions on [asynchronous providers](futures.state#def:asynchronous_provider "32.10.5 Shared state [futures.state]") or by the move constructor and shares its shared state with
|
||
the original asynchronous provider[.](#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[.](#1.sentence-4)
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11739)
|
||
|
||
[*Note [1](#note-1)*:
|
||
|
||
Member functions of future do not synchronize with themselves or with
|
||
member functions of shared_future[.](#2.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[3](#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[.](#3.sentence-1)
|
||
|
||
[*Note [2](#note-2)*:
|
||
|
||
It is valid to move from a future object for which valid() == false[.](#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[.](#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](#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.2 Template argument requirements [utility.arg.requirements]") requirements[.](#4.sentence-1)
|
||
|
||
[5](#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>[.](#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[.](#5.sentence-2)
|
||
|
||
[ð](#lib:future,constructor)
|
||
|
||
`future() noexcept;
|
||
`
|
||
|
||
[6](#6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11802)
|
||
|
||
*Effects*: The object does not refer to a shared state[.](#6.sentence-1)
|
||
|
||
[7](#7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11806)
|
||
|
||
*Postconditions*: valid() == false[.](#7.sentence-1)
|
||
|
||
[ð](#lib:future,constructor_)
|
||
|
||
`future(future&& rhs) noexcept;
|
||
`
|
||
|
||
[8](#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)[.](#8.sentence-1)
|
||
|
||
[9](#9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11823)
|
||
|
||
*Postconditions*:
|
||
|
||
- [(9.1)](#9.1)
|
||
|
||
valid() returns the same value as rhs.valid() prior to the
|
||
constructor invocation[.](#9.1.sentence-1)
|
||
|
||
- [(9.2)](#9.2)
|
||
|
||
rhs.valid() == false[.](#9.2.sentence-1)
|
||
|
||
[ð](#lib:future,constructor__)
|
||
|
||
`~future();
|
||
`
|
||
|
||
[10](#10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11838)
|
||
|
||
*Effects*:
|
||
|
||
- [(10.1)](#10.1)
|
||
|
||
Releases any shared state ([[futures.state]](futures.state "32.10.5 Shared state"));
|
||
|
||
- [(10.2)](#10.2)
|
||
|
||
destroys *this[.](#10.sentence-1)
|
||
|
||
[ð](#lib:operator=,future)
|
||
|
||
`future& operator=(future&& rhs) noexcept;
|
||
`
|
||
|
||
[11](#11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11854)
|
||
|
||
*Effects*: If addressof(rhs) == this is true, there are no effects[.](#11.sentence-1)
|
||
|
||
Otherwise:
|
||
|
||
- [(11.1)](#11.1)
|
||
|
||
Releases any shared state ([[futures.state]](futures.state "32.10.5 Shared state"))[.](#11.1.sentence-1)
|
||
|
||
- [(11.2)](#11.2)
|
||
|
||
move assigns the contents of rhs to *this[.](#11.2.sentence-1)
|
||
|
||
[12](#12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11865)
|
||
|
||
*Postconditions*:
|
||
|
||
- [(12.1)](#12.1)
|
||
|
||
valid() returns the same value as rhs.valid() prior to the
|
||
assignment[.](#12.1.sentence-1)
|
||
|
||
- [(12.2)](#12.2)
|
||
|
||
If addressof(rhs) == this is false,rhs.valid() == false[.](#12.2.sentence-1)
|
||
|
||
[ð](#lib:share,future)
|
||
|
||
`shared_future<R> share() noexcept;
|
||
`
|
||
|
||
[13](#13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11884)
|
||
|
||
*Postconditions*: valid() == false[.](#13.sentence-1)
|
||
|
||
[14](#14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11888)
|
||
|
||
*Returns*: shared_future<R>(std::move(*this))[.](#14.sentence-1)
|
||
|
||
[ð](#lib:get,future)
|
||
|
||
`R future::get();
|
||
R& future<R&>::get();
|
||
void future<void>::get();
|
||
`
|
||
|
||
[15](#15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11901)
|
||
|
||
[*Note [3](#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[.](#15.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[16](#16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11907)
|
||
|
||
*Effects*:
|
||
|
||
- [(16.1)](#16.1)
|
||
|
||
wait()s until the shared state is ready, then retrieves the
|
||
value stored in the shared state;
|
||
|
||
- [(16.2)](#16.2)
|
||
|
||
releases any shared state ([[futures.state]](futures.state "32.10.5 Shared state"))[.](#16.sentence-1)
|
||
|
||
[17](#17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11915)
|
||
|
||
*Postconditions*: valid() == false[.](#17.sentence-1)
|
||
|
||
[18](#18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11919)
|
||
|
||
*Returns*:
|
||
|
||
- [(18.1)](#18.1)
|
||
|
||
future::get() returns the value v stored in the object's shared state asstd::move(v)[.](#18.1.sentence-1)
|
||
|
||
- [(18.2)](#18.2)
|
||
|
||
future<R&>::get() returns the reference stored as value in the object's shared state[.](#18.2.sentence-1)
|
||
|
||
- [(18.3)](#18.3)
|
||
|
||
future<void>::get() returns nothing[.](#18.3.sentence-1)
|
||
|
||
[19](#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[.](#19.sentence-1)
|
||
|
||
[ð](#lib:valid,future)
|
||
|
||
`bool valid() const noexcept;
|
||
`
|
||
|
||
[20](#20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11944)
|
||
|
||
*Returns*: true only if *this refers to a shared state[.](#20.sentence-1)
|
||
|
||
[ð](#lib:wait,future)
|
||
|
||
`void wait() const;
|
||
`
|
||
|
||
[21](#21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11955)
|
||
|
||
*Effects*: Blocks until the shared state is ready[.](#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](#22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11968)
|
||
|
||
*Effects*: None if the shared state contains a deferred function ([[futures.async]](futures.async "32.10.9 Function template async")),
|
||
otherwise
|
||
blocks until the shared state is ready or until
|
||
the relative timeout ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications")) specified by rel_time has expired[.](#22.sentence-1)
|
||
|
||
[23](#23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11976)
|
||
|
||
*Returns*:
|
||
|
||
- [(23.1)](#23.1)
|
||
|
||
future_status::deferred if the shared state contains a deferred
|
||
function[.](#23.1.sentence-1)
|
||
|
||
- [(23.2)](#23.2)
|
||
|
||
future_status::ready if the shared state is ready[.](#23.2.sentence-1)
|
||
|
||
- [(23.3)](#23.3)
|
||
|
||
future_status::timeout if the function is returning because the
|
||
relative timeout ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications"))
|
||
specified by rel_time has expired[.](#23.3.sentence-1)
|
||
|
||
[24](#24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L11989)
|
||
|
||
*Throws*: timeout-related exceptions ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications"))[.](#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](#25)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12001)
|
||
|
||
*Effects*: None if the shared state contains a deferred function ([[futures.async]](futures.async "32.10.9 Function template async")),
|
||
otherwise
|
||
blocks until the shared state is ready or until
|
||
the absolute timeout ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications")) specified by abs_time has expired[.](#25.sentence-1)
|
||
|
||
[26](#26)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12009)
|
||
|
||
*Returns*:
|
||
|
||
- [(26.1)](#26.1)
|
||
|
||
future_status::deferred if the shared state contains a deferred
|
||
function[.](#26.1.sentence-1)
|
||
|
||
- [(26.2)](#26.2)
|
||
|
||
future_status::ready if the shared state is ready[.](#26.2.sentence-1)
|
||
|
||
- [(26.3)](#26.3)
|
||
|
||
future_status::timeout if the function is returning because the
|
||
absolute timeout ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications"))
|
||
specified by abs_time has expired[.](#26.3.sentence-1)
|
||
|
||
[27](#27)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12023)
|
||
|
||
*Throws*: timeout-related exceptions ([[thread.req.timing]](thread.req.timing "32.2.4 Timing specifications"))[.](#27.sentence-1)
|