Init
This commit is contained in:
393
cppdraft/futures/task.md
Normal file
393
cppdraft/futures/task.md
Normal file
@@ -0,0 +1,393 @@
|
||||
[futures.task]
|
||||
|
||||
# 32 Concurrency support library [[thread]](./#thread)
|
||||
|
||||
## 32.10 Futures [[futures]](futures#task)
|
||||
|
||||
### 32.10.10 Class template packaged_task [futures.task]
|
||||
|
||||
#### [32.10.10.1](#general) General [[futures.task.general]](futures.task.general)
|
||||
|
||||
[1](#general-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12544)
|
||||
|
||||
The class template packaged_task defines a type for wrapping a function or
|
||||
callable object so that the return value of the function or callable object is stored in
|
||||
a future when it is invoked[.](#general-1.sentence-1)
|
||||
|
||||
[2](#general-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12549)
|
||||
|
||||
When the packaged_task object is invoked, its stored task is invoked and the
|
||||
result (whether normal or exceptional) stored in the shared state[.](#general-2.sentence-1)
|
||||
|
||||
Any futures that
|
||||
share the shared state will then be able to access the stored result[.](#general-2.sentence-2)
|
||||
|
||||
[ð](#lib:packaged_task)
|
||||
|
||||
namespace std {template<class> class packaged_task; // *not defined*template<class R, class... ArgTypes>class packaged_task<R(ArgTypes...)> {public:// construction and destruction packaged_task() noexcept; template<class F>explicit packaged_task(F&& f); template<class F, class Allocator>explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f); ~packaged_task(); // no copy packaged_task(const packaged_task&) = delete;
|
||||
packaged_task& operator=(const packaged_task&) = delete; // move support packaged_task(packaged_task&& rhs) noexcept;
|
||||
packaged_task& operator=(packaged_task&& rhs) noexcept; void swap(packaged_task& other) noexcept; bool valid() const noexcept; // result retrieval future<R> get_future(); // executionvoid operator()(ArgTypes... ); void make_ready_at_thread_exit(ArgTypes...); void reset(); }; template<class R, class... ArgTypes> packaged_task(R (*)(ArgTypes...)) -> packaged_task<R(ArgTypes...)>; template<class F> packaged_task(F) -> packaged_task<*see below*>;}
|
||||
|
||||
#### [32.10.10.2](#members) Member functions [[futures.task.members]](futures.task.members)
|
||||
|
||||
[ð](#lib:packaged_task,constructor)
|
||||
|
||||
`packaged_task() noexcept;
|
||||
`
|
||||
|
||||
[1](#members-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12606)
|
||||
|
||||
*Effects*: The object has no shared state and no stored task[.](#members-1.sentence-1)
|
||||
|
||||
[ð](#lib:packaged_task,constructor_)
|
||||
|
||||
`template<class F>
|
||||
explicit packaged_task(F&& f);
|
||||
`
|
||||
|
||||
[2](#members-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12618)
|
||||
|
||||
*Effects*: Equivalent topackaged_task(allocator_arg, allocator<int>(), std::forward<F>(f))[.](#members-2.sentence-1)
|
||||
|
||||
[ð](#lib:packaged_task,constructor__)
|
||||
|
||||
`template<class F, class Allocator>
|
||||
explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
|
||||
`
|
||||
|
||||
[3](#members-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12631)
|
||||
|
||||
*Constraints*: remove_cvref_t<F> is not the same type as packaged_task<R(ArgTypes...)>[.](#members-3.sentence-1)
|
||||
|
||||
[4](#members-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12636)
|
||||
|
||||
*Mandates*: is_invocable_r_v<R, decay_t<F>&, ArgTypes...> is true[.](#members-4.sentence-1)
|
||||
|
||||
[5](#members-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12640)
|
||||
|
||||
*Preconditions*: Allocator meets the *Cpp17Allocator* requirements ([[allocator.requirements.general]](allocator.requirements.general "16.4.4.6.1 General"))[.](#members-5.sentence-1)
|
||||
|
||||
[6](#members-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12644)
|
||||
|
||||
*Effects*: Let A2 beallocator_traits<Allocator>::rebind_alloc<*unspecified*> and let a2 be an object of type A2 initialized withA2(a)[.](#members-6.sentence-1)
|
||||
|
||||
Constructs a new packaged_task object with
|
||||
a stored task of type decay_t<F> and a shared state[.](#members-6.sentence-2)
|
||||
|
||||
Initializes the object's stored task with std::forward<F>(f)[.](#members-6.sentence-3)
|
||||
|
||||
Uses a2 to allocate storage for the shared state and stores a copy
|
||||
of a2 in the shared state[.](#members-6.sentence-4)
|
||||
|
||||
[7](#members-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12656)
|
||||
|
||||
*Throws*: Any exceptions thrown by the initialization of the stored task[.](#members-7.sentence-1)
|
||||
|
||||
If storage for the shared state cannot be allocated, any exception thrown byA2::allocate[.](#members-7.sentence-2)
|
||||
|
||||
[ð](#lib:packaged_task,constructor___)
|
||||
|
||||
`template<class F> packaged_task(F) -> packaged_task<see below>;
|
||||
`
|
||||
|
||||
[8](#members-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12669)
|
||||
|
||||
*Constraints*: &F::operator() is well-formed when
|
||||
treated as an unevaluated operand ([[expr.context]](expr.context#term.unevaluated.operand "7.2.3 Context dependence")) and either
|
||||
|
||||
- [(8.1)](#members-8.1)
|
||||
|
||||
F::operator() is a non-static member function anddecltype(&F::operator()) is either of the formR(G::*)(A...) cv &opt noexceptopt or of the formR(*)(G, A...) noexceptopt for a type G, or
|
||||
|
||||
- [(8.2)](#members-8.2)
|
||||
|
||||
F::operator() is a static member function anddecltype(&F::operator()) is of the formR(*)(A...) noexceptopt[.](#members-8.sentence-1)
|
||||
|
||||
[9](#members-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12687)
|
||||
|
||||
*Remarks*: The deduced type is packaged_task<R(A...)>[.](#members-9.sentence-1)
|
||||
|
||||
[ð](#lib:packaged_task,constructor____)
|
||||
|
||||
`packaged_task(packaged_task&& rhs) noexcept;
|
||||
`
|
||||
|
||||
[10](#members-10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12698)
|
||||
|
||||
*Effects*: Transfers ownership ofrhs's shared state to *this, leaving rhs with no
|
||||
shared state[.](#members-10.sentence-1)
|
||||
|
||||
Moves the stored task from rhs to *this[.](#members-10.sentence-2)
|
||||
|
||||
[11](#members-11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12704)
|
||||
|
||||
*Postconditions*: rhs has no shared state[.](#members-11.sentence-1)
|
||||
|
||||
[ð](#lib:operator=,packaged_task)
|
||||
|
||||
`packaged_task& operator=(packaged_task&& rhs) noexcept;
|
||||
`
|
||||
|
||||
[12](#members-12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12715)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(12.1)](#members-12.1)
|
||||
|
||||
Releases any shared state ([[futures.state]](futures.state "32.10.5 Shared state"));
|
||||
|
||||
- [(12.2)](#members-12.2)
|
||||
|
||||
calls packaged_task(std::move(rhs)).swap(*this)[.](#members-12.sentence-1)
|
||||
|
||||
[ð](#lib:packaged_task,destructor)
|
||||
|
||||
`~packaged_task();
|
||||
`
|
||||
|
||||
[13](#members-13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12731)
|
||||
|
||||
*Effects*: Abandons any shared state ([[futures.state]](futures.state "32.10.5 Shared state"))[.](#members-13.sentence-1)
|
||||
|
||||
[ð](#lib:swap,packaged_task)
|
||||
|
||||
`void swap(packaged_task& other) noexcept;
|
||||
`
|
||||
|
||||
[14](#members-14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12742)
|
||||
|
||||
*Effects*: Exchanges the shared states and stored tasks of *this and other[.](#members-14.sentence-1)
|
||||
|
||||
[15](#members-15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12746)
|
||||
|
||||
*Postconditions*: *this has the same shared state
|
||||
and stored task (if any) as other prior to the call to swap[.](#members-15.sentence-1)
|
||||
|
||||
other has the same shared state
|
||||
and stored task (if any)
|
||||
as *this prior to the call to swap[.](#members-15.sentence-2)
|
||||
|
||||
[ð](#lib:valid,packaged_task)
|
||||
|
||||
`bool valid() const noexcept;
|
||||
`
|
||||
|
||||
[16](#members-16)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12761)
|
||||
|
||||
*Returns*: true only if *this has a shared state[.](#members-16.sentence-1)
|
||||
|
||||
[ð](#lib:get_future,packaged_task)
|
||||
|
||||
`future<R> get_future();
|
||||
`
|
||||
|
||||
[17](#members-17)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12772)
|
||||
|
||||
*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 tooperator() ormake_ready_at_thread_exit[.](#members-17.sentence-1)
|
||||
|
||||
[*Note [1](#members-note-1)*:
|
||||
|
||||
Such calls need not synchronize with each other[.](#members-17.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[18](#members-18)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12782)
|
||||
|
||||
*Returns*: A future object that shares the same shared state as *this[.](#members-18.sentence-1)
|
||||
|
||||
[19](#members-19)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12786)
|
||||
|
||||
*Throws*: A future_error object if an error occurs[.](#members-19.sentence-1)
|
||||
|
||||
[20](#members-20)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12790)
|
||||
|
||||
*Error conditions*:
|
||||
|
||||
- [(20.1)](#members-20.1)
|
||||
|
||||
future_already_retrieved if get_future has already been called on
|
||||
a packaged_task object with the same shared state as *this[.](#members-20.1.sentence-1)
|
||||
|
||||
- [(20.2)](#members-20.2)
|
||||
|
||||
no_state if *this has no shared state[.](#members-20.2.sentence-1)
|
||||
|
||||
[ð](#lib:operator(),packaged_task)
|
||||
|
||||
`void operator()(ArgTypes... args);
|
||||
`
|
||||
|
||||
[21](#members-21)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12805)
|
||||
|
||||
*Effects*: As if by *INVOKE*<R>(f, t1, t2, …, tN) ([[func.require]](func.require "22.10.4 Requirements")),
|
||||
where f is the
|
||||
stored task of *this andt1, t2, …, tN are the values in args...[.](#members-21.sentence-1)
|
||||
|
||||
If the task returns normally,
|
||||
the return value is stored as the asynchronous result in the shared state of*this, otherwise the exception thrown by the task is stored[.](#members-21.sentence-2)
|
||||
|
||||
The
|
||||
shared state of *this is made ready, and any threads blocked in a
|
||||
function waiting for
|
||||
the shared state of *this to become ready are unblocked[.](#members-21.sentence-3)
|
||||
|
||||
[22](#members-22)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12817)
|
||||
|
||||
*Throws*: A future_error exception object if there is no shared
|
||||
state or the stored task has already been invoked[.](#members-22.sentence-1)
|
||||
|
||||
[23](#members-23)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12822)
|
||||
|
||||
*Error conditions*:
|
||||
|
||||
- [(23.1)](#members-23.1)
|
||||
|
||||
promise_already_satisfied if
|
||||
the stored task has already been invoked[.](#members-23.1.sentence-1)
|
||||
|
||||
- [(23.2)](#members-23.2)
|
||||
|
||||
no_state if *this has no shared state[.](#members-23.2.sentence-1)
|
||||
|
||||
[ð](#lib:make_ready_at_thread_exit,packaged_task)
|
||||
|
||||
`void make_ready_at_thread_exit(ArgTypes... args);
|
||||
`
|
||||
|
||||
[24](#members-24)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12837)
|
||||
|
||||
*Effects*: As if by *INVOKE*<R>(f, t1, t2, …, tN) ([[func.require]](func.require "22.10.4 Requirements")),
|
||||
where f is the stored task andt1, t2, …, tN are the values in args...[.](#members-24.sentence-1)
|
||||
|
||||
If the task returns normally,
|
||||
the return value is stored as the asynchronous result in the shared state of*this, otherwise the exception thrown by the task is stored[.](#members-24.sentence-2)
|
||||
|
||||
In either
|
||||
case, this is done without making that state ready ([[futures.state]](futures.state "32.10.5 Shared state")) immediately[.](#members-24.sentence-3)
|
||||
|
||||
Schedules
|
||||
the shared 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[.](#members-24.sentence-4)
|
||||
|
||||
[25](#members-25)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12849)
|
||||
|
||||
*Throws*: future_error if an error condition occurs[.](#members-25.sentence-1)
|
||||
|
||||
[26](#members-26)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12853)
|
||||
|
||||
*Error conditions*:
|
||||
|
||||
- [(26.1)](#members-26.1)
|
||||
|
||||
promise_already_satisfied if the
|
||||
stored task has already been invoked[.](#members-26.1.sentence-1)
|
||||
|
||||
- [(26.2)](#members-26.2)
|
||||
|
||||
no_state if *this has no shared state[.](#members-26.2.sentence-1)
|
||||
|
||||
[ð](#lib:reset,packaged_task)
|
||||
|
||||
`void reset();
|
||||
`
|
||||
|
||||
[27](#members-27)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12868)
|
||||
|
||||
*Effects*: Equivalent to:if (!valid()) {throw future_error(future_errc::no_state);}*this = packaged_task(allocator_arg, a, std::move(f)); wheref is the task stored in*this and a is the allocator stored in the shared state[.](#members-27.sentence-1)
|
||||
|
||||
[*Note [2](#members-note-2)*:
|
||||
|
||||
This constructs a new shared state for *this[.](#members-27.sentence-2)
|
||||
|
||||
The
|
||||
old state is abandoned ([[futures.state]](futures.state "32.10.5 Shared state"))[.](#members-27.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[28](#members-28)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12885)
|
||||
|
||||
*Throws*:
|
||||
|
||||
- [(28.1)](#members-28.1)
|
||||
|
||||
Any exception thrown by the packaged_task constructor[.](#members-28.1.sentence-1)
|
||||
|
||||
- [(28.2)](#members-28.2)
|
||||
|
||||
future_error with an error condition of no_state if *this has no shared state[.](#members-28.2.sentence-1)
|
||||
|
||||
#### [32.10.10.3](#nonmembers) Globals [[futures.task.nonmembers]](futures.task.nonmembers)
|
||||
|
||||
[ð](#lib:swap,packaged_task_)
|
||||
|
||||
`template<class R, class... ArgTypes>
|
||||
void swap(packaged_task<R(ArgTypes...)>& x, packaged_task<R(ArgTypes...)>& y) noexcept;
|
||||
`
|
||||
|
||||
[1](#nonmembers-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L12903)
|
||||
|
||||
*Effects*: As if by x.swap(y)[.](#nonmembers-1.sentence-1)
|
||||
Reference in New Issue
Block a user