Init
This commit is contained in:
366
cppdraft/futures/unique/future.md
Normal file
366
cppdraft/futures/unique/future.md
Normal file
@@ -0,0 +1,366 @@
|
||||
[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)
|
||||
Reference in New Issue
Block a user