tmp/tmpsvtgkt5o/{from.md → to.md}
RENAMED
|
@@ -4,100 +4,101 @@ The function template `async` provides a mechanism to launch a function
|
|
| 4 |
potentially in a new thread and provides the result of the function in a
|
| 5 |
`future` object with which it shares a shared state.
|
| 6 |
|
| 7 |
``` cpp
|
| 8 |
template<class F, class... Args>
|
| 9 |
-
future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
|
| 10 |
async(F&& f, Args&&... args);
|
| 11 |
template<class F, class... Args>
|
| 12 |
-
future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
|
| 13 |
async(launch policy, F&& f, Args&&... args);
|
| 14 |
```
|
| 15 |
|
| 16 |
-
*
|
| 17 |
-
`MoveConstructible` requirements, and
|
| 18 |
|
| 19 |
-
`
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
``
|
|
|
|
| 23 |
|
| 24 |
-
|
|
|
|
| 25 |
|
| 26 |
*Effects:* The first function behaves the same as a call to the second
|
| 27 |
function with a `policy` argument of `launch::async | launch::deferred`
|
| 28 |
and the same arguments for `F` and `Args`. The second function creates a
|
| 29 |
shared state that is associated with the returned `future` object. The
|
| 30 |
further behavior of the second function depends on the `policy` argument
|
| 31 |
as follows (if more than one of these conditions applies, the
|
| 32 |
implementation may choose any of the corresponding policies):
|
| 33 |
|
| 34 |
- If `launch::async` is set in `policy`, calls
|
| 35 |
-
|
| 36 |
-
*
|
| 37 |
[[thread.thread.constr]]) as if in a new thread of execution
|
| 38 |
-
represented by a `thread` object with the calls to *
|
| 39 |
being evaluated in the thread that called `async`. Any return value is
|
| 40 |
stored as the result in the shared state. Any exception propagated
|
| 41 |
-
from the execution of
|
| 42 |
-
*
|
| 43 |
-
exceptional result in the shared state. The `thread`
|
| 44 |
-
in the shared state and affects the behavior of any
|
| 45 |
-
return objects that reference that state.
|
| 46 |
- If `launch::deferred` is set in `policy`, stores
|
| 47 |
-
*
|
| 48 |
-
*
|
| 49 |
copies of `f` and `args` constitute a *deferred function*. Invocation
|
| 50 |
-
of the deferred function evaluates
|
| 51 |
-
std::move(xyz)) where `g` is the stored value
|
| 52 |
-
*
|
| 53 |
-
*
|
| 54 |
stored as the result in the shared state. Any exception propagated
|
| 55 |
from the execution of the deferred function is stored as the
|
| 56 |
exceptional result in the shared state. The shared state is not made
|
| 57 |
ready until the function has completed. The first call to a non-timed
|
| 58 |
-
waiting function
|
| 59 |
-
referring to this shared state
|
| 60 |
-
|
| 61 |
-
|
| 62 |
longer considered deferred. \[*Note 1*: If this policy is specified
|
| 63 |
together with other policies, such as when using a `policy` value of
|
| 64 |
`launch::async | launch::deferred`, implementations should defer
|
| 65 |
invocation or the selection of the policy when no more concurrency can
|
| 66 |
be effectively exploited. — *end note*]
|
| 67 |
- If no value is set in the launch policy, or a value is set that is
|
| 68 |
-
neither specified in this
|
| 69 |
-
|
| 70 |
|
| 71 |
*Returns:* An object of type
|
| 72 |
`future<invoke_result_t<decay_t<F>, decay_t<Args>...>``>` that refers to
|
| 73 |
the shared state created by this call to `async`.
|
| 74 |
|
| 75 |
[*Note 1*: If a future obtained from `async` is moved outside the local
|
| 76 |
-
scope, other code that uses the future
|
| 77 |
-
destructor
|
| 78 |
ready. — *end note*]
|
| 79 |
|
| 80 |
*Synchronization:* Regardless of the provided `policy` argument,
|
| 81 |
|
| 82 |
-
- the invocation of `async` synchronizes with
|
| 83 |
-
|
| 84 |
-
|
| 85 |
thread. — *end note*] ; and
|
| 86 |
- the completion of the function `f` is sequenced
|
| 87 |
-
before
|
| 88 |
\[*Note 3*: `f` might not be called at all, so its completion might
|
| 89 |
never happen. — *end note*]
|
| 90 |
|
| 91 |
If the implementation chooses the `launch::async` policy,
|
| 92 |
|
| 93 |
- a call to a waiting function on an asynchronous return object that
|
| 94 |
shares the shared state created by this `async` call shall block until
|
| 95 |
the associated thread has completed, as if joined, or else time
|
| 96 |
-
out
|
| 97 |
- the associated thread completion synchronizes
|
| 98 |
-
with
|
| 99 |
successfully detects the ready status of the shared state or with the
|
| 100 |
return from the last function that releases the shared state,
|
| 101 |
whichever happens first.
|
| 102 |
|
| 103 |
*Throws:* `system_error` if `policy == launch::async` and the
|
|
|
|
| 4 |
potentially in a new thread and provides the result of the function in a
|
| 5 |
`future` object with which it shares a shared state.
|
| 6 |
|
| 7 |
``` cpp
|
| 8 |
template<class F, class... Args>
|
| 9 |
+
[[nodiscard]] future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
|
| 10 |
async(F&& f, Args&&... args);
|
| 11 |
template<class F, class... Args>
|
| 12 |
+
[[nodiscard]] future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
|
| 13 |
async(launch policy, F&& f, Args&&... args);
|
| 14 |
```
|
| 15 |
|
| 16 |
+
*Mandates:* The following are all `true`:
|
|
|
|
| 17 |
|
| 18 |
+
- `is_constructible_v<decay_t<F>, F>`,
|
| 19 |
+
- `(is_constructible_v<decay_t<Args>, Args> &&...)`,
|
| 20 |
+
- `is_move_constructible_v<decay_t<F>>`,
|
| 21 |
+
- `(is_move_constructible_v<decay_t<Args>> &&...)`, and
|
| 22 |
+
- `is_invocable_v<decay_t<F>, decay_t<Args>...>`.
|
| 23 |
|
| 24 |
+
*Preconditions:* `decay_t<F>` and each type in `decay_t<Args>` meet the
|
| 25 |
+
*Cpp17MoveConstructible* requirements.
|
| 26 |
|
| 27 |
*Effects:* The first function behaves the same as a call to the second
|
| 28 |
function with a `policy` argument of `launch::async | launch::deferred`
|
| 29 |
and the same arguments for `F` and `Args`. The second function creates a
|
| 30 |
shared state that is associated with the returned `future` object. The
|
| 31 |
further behavior of the second function depends on the `policy` argument
|
| 32 |
as follows (if more than one of these conditions applies, the
|
| 33 |
implementation may choose any of the corresponding policies):
|
| 34 |
|
| 35 |
- If `launch::async` is set in `policy`, calls
|
| 36 |
+
`invoke(`*`decay-copy`*`(std::forward<F>(f)),`
|
| 37 |
+
*decay-copy*(std::forward\<Args\>(args))...) ([[func.require]],
|
| 38 |
[[thread.thread.constr]]) as if in a new thread of execution
|
| 39 |
+
represented by a `thread` object with the calls to *`decay-copy`*
|
| 40 |
being evaluated in the thread that called `async`. Any return value is
|
| 41 |
stored as the result in the shared state. Any exception propagated
|
| 42 |
+
from the execution of
|
| 43 |
+
`invoke(`*`decay-copy`*`(std::forward<F>(f)), `*`decay-copy`*`(std::forward<Args>(args))...)`
|
| 44 |
+
is stored as the exceptional result in the shared state. The `thread`
|
| 45 |
+
object is stored in the shared state and affects the behavior of any
|
| 46 |
+
asynchronous return objects that reference that state.
|
| 47 |
- If `launch::deferred` is set in `policy`, stores
|
| 48 |
+
*decay-copy*(std::forward\<F\>(f)) and
|
| 49 |
+
*decay-copy*(std::forward\<Args\>(args))... in the shared state. These
|
| 50 |
copies of `f` and `args` constitute a *deferred function*. Invocation
|
| 51 |
+
of the deferred function evaluates
|
| 52 |
+
`invoke(std::move(g), std::move(xyz))` where `g` is the stored value
|
| 53 |
+
of *decay-copy*(std::forward\<F\>(f)) and `xyz` is the stored copy of
|
| 54 |
+
*decay-copy*(std::forward\<Args\>(args)).... Any return value is
|
| 55 |
stored as the result in the shared state. Any exception propagated
|
| 56 |
from the execution of the deferred function is stored as the
|
| 57 |
exceptional result in the shared state. The shared state is not made
|
| 58 |
ready until the function has completed. The first call to a non-timed
|
| 59 |
+
waiting function [[futures.state]] on an asynchronous return object
|
| 60 |
+
referring to this shared state invokes the deferred function in the
|
| 61 |
+
thread that called the waiting function. Once evaluation of
|
| 62 |
+
`invoke(std::move(g), std::move(xyz))` begins, the function is no
|
| 63 |
longer considered deferred. \[*Note 1*: If this policy is specified
|
| 64 |
together with other policies, such as when using a `policy` value of
|
| 65 |
`launch::async | launch::deferred`, implementations should defer
|
| 66 |
invocation or the selection of the policy when no more concurrency can
|
| 67 |
be effectively exploited. — *end note*]
|
| 68 |
- If no value is set in the launch policy, or a value is set that is
|
| 69 |
+
neither specified in this document nor by the implementation, the
|
| 70 |
+
behavior is undefined.
|
| 71 |
|
| 72 |
*Returns:* An object of type
|
| 73 |
`future<invoke_result_t<decay_t<F>, decay_t<Args>...>``>` that refers to
|
| 74 |
the shared state created by this call to `async`.
|
| 75 |
|
| 76 |
[*Note 1*: If a future obtained from `async` is moved outside the local
|
| 77 |
+
scope, other code that uses the future should be aware that the future’s
|
| 78 |
+
destructor can block for the shared state to become
|
| 79 |
ready. — *end note*]
|
| 80 |
|
| 81 |
*Synchronization:* Regardless of the provided `policy` argument,
|
| 82 |
|
| 83 |
+
- the invocation of `async` synchronizes with [[intro.multithread]] the
|
| 84 |
+
invocation of `f`. \[*Note 2*: This statement applies even when the
|
| 85 |
+
corresponding `future` object is moved to another
|
| 86 |
thread. — *end note*] ; and
|
| 87 |
- the completion of the function `f` is sequenced
|
| 88 |
+
before [[intro.multithread]] the shared state is made ready.
|
| 89 |
\[*Note 3*: `f` might not be called at all, so its completion might
|
| 90 |
never happen. — *end note*]
|
| 91 |
|
| 92 |
If the implementation chooses the `launch::async` policy,
|
| 93 |
|
| 94 |
- a call to a waiting function on an asynchronous return object that
|
| 95 |
shares the shared state created by this `async` call shall block until
|
| 96 |
the associated thread has completed, as if joined, or else time
|
| 97 |
+
out [[thread.thread.member]];
|
| 98 |
- the associated thread completion synchronizes
|
| 99 |
+
with [[intro.multithread]] the return from the first function that
|
| 100 |
successfully detects the ready status of the shared state or with the
|
| 101 |
return from the last function that releases the shared state,
|
| 102 |
whichever happens first.
|
| 103 |
|
| 104 |
*Throws:* `system_error` if `policy == launch::async` and the
|