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.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.5Shared 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.2Template 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.5Shared 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.5Shared 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.5Shared 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.9Function template async")),
otherwise
blocks until the shared state is ready or until
the relative timeout ([[thread.req.timing]](thread.req.timing "32.2.4Timing 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.4Timing 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.4Timing 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.9Function template async")),
otherwise
blocks until the shared state is ready or until
the absolute timeout ([[thread.req.timing]](thread.req.timing "32.2.4Timing 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.4Timing 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.4Timing specifications"))[.](#27.sentence-1)