tmp/tmphkkqr84b/{from.md → to.md}
RENAMED
|
@@ -14,82 +14,64 @@ template<class F, class... 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(
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 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 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
of the deferred function evaluates
|
| 52 |
`invoke(std::move(g), std::move(xyz))` where `g` is the stored value
|
| 53 |
-
of
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
`invoke(std::move(g), std::move(xyz))` begins, the function is no
|
| 63 |
-
longer considered deferred.
|
| 64 |
-
together with other policies, such as when using a `policy`
|
| 65 |
-
`launch::async | launch::deferred`, implementations should
|
| 66 |
-
invocation or the selection of the policy when no more
|
| 67 |
-
be effectively exploited.
|
| 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 |
-
*
|
| 73 |
-
|
| 74 |
-
the shared state
|
| 75 |
|
| 76 |
-
[*Note 1*:
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 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
|
|
@@ -99,20 +81,28 @@ If the implementation chooses the `launch::async` policy,
|
|
| 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
|
| 105 |
implementation is unable to start a new thread, or `std::bad_alloc` if
|
| 106 |
-
memory for the internal data structures
|
| 107 |
|
| 108 |
*Error conditions:*
|
| 109 |
|
| 110 |
- `resource_unavailable_try_again` — if `policy == launch::async` and
|
| 111 |
the system is unable to start a new thread.
|
| 112 |
|
| 113 |
-
[*Note
|
| 114 |
-
call uses the default policy, which
|
| 115 |
-
case the lambda might not be invoked until the `get()` call; in
|
| 116 |
-
case, `work1` and `work2` are called on the same thread and there
|
| 117 |
-
concurrency. — *end note*]
|
| 118 |
|
|
|
|
| 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> && ...)`, and
|
|
|
|
|
|
|
| 20 |
- `is_invocable_v<decay_t<F>, decay_t<Args>...>`.
|
| 21 |
|
|
|
|
|
|
|
|
|
|
| 22 |
*Effects:* The first function behaves the same as a call to the second
|
| 23 |
function with a `policy` argument of `launch::async | launch::deferred`
|
| 24 |
and the same arguments for `F` and `Args`. The second function creates a
|
| 25 |
shared state that is associated with the returned `future` object. The
|
| 26 |
further behavior of the second function depends on the `policy` argument
|
| 27 |
as follows (if more than one of these conditions applies, the
|
| 28 |
implementation may choose any of the corresponding policies):
|
| 29 |
|
| 30 |
- If `launch::async` is set in `policy`, calls
|
| 31 |
+
`invoke(auto(std::forward<F>(f)), auto(std::forward<Args>(args))...)`
|
| 32 |
+
[[func.invoke]], [[thread.thread.constr]] as if in a new thread of
|
| 33 |
+
execution represented by a `thread` object with the values produced by
|
| 34 |
+
`auto` being materialized [[conv.rval]] in the thread that called
|
| 35 |
+
`async`. Any return value is stored as the result in the shared state.
|
| 36 |
+
Any exception propagated from the execution of
|
| 37 |
+
`invoke(auto(std::forward<F>(f)), auto(std::forward<Args>(args))...)`
|
|
|
|
| 38 |
is stored as the exceptional result in the shared state. The `thread`
|
| 39 |
object is stored in the shared state and affects the behavior of any
|
| 40 |
asynchronous return objects that reference that state.
|
| 41 |
- If `launch::deferred` is set in `policy`, stores
|
| 42 |
+
`auto(std::forward<F>(f))` and `auto(std::forward<Args>(args))...` in
|
| 43 |
+
the shared state. These copies of `f` and `args` constitute a
|
| 44 |
+
*deferred function*. Invocation of the deferred function evaluates
|
|
|
|
| 45 |
`invoke(std::move(g), std::move(xyz))` where `g` is the stored value
|
| 46 |
+
of `auto(std::forward<F>(f))` and `xyz` is the stored copy of
|
| 47 |
+
`auto(std::forward<Args>(args))...`. Any return value is stored as the
|
| 48 |
+
result in the shared state. Any exception propagated from the
|
| 49 |
+
execution of the deferred function is stored as the exceptional result
|
| 50 |
+
in the shared state. The shared state is not made ready until the
|
| 51 |
+
function has completed. The first call to a non-timed waiting
|
| 52 |
+
function [[futures.state]] on an asynchronous return object referring
|
| 53 |
+
to this shared state invokes the deferred function in the thread that
|
| 54 |
+
called the waiting function. Once evaluation of
|
| 55 |
`invoke(std::move(g), std::move(xyz))` begins, the function is no
|
| 56 |
+
longer considered deferred. *Recommended practice:* If this policy is
|
| 57 |
+
specified together with other policies, such as when using a `policy`
|
| 58 |
+
value of `launch::async | launch::deferred`, implementations should
|
| 59 |
+
defer invocation or the selection of the policy when no more
|
| 60 |
+
concurrency can be effectively exploited.
|
| 61 |
- If no value is set in the launch policy, or a value is set that is
|
| 62 |
neither specified in this document nor by the implementation, the
|
| 63 |
behavior is undefined.
|
| 64 |
|
| 65 |
+
*Synchronization:* The invocation of `async` synchronizes with the
|
| 66 |
+
invocation of `f`. The completion of the function `f` is sequenced
|
| 67 |
+
before the shared state is made ready.
|
| 68 |
|
| 69 |
+
[*Note 1*: These apply regardless of the provided `policy` argument,
|
| 70 |
+
and even if the corresponding `future` object is moved to another
|
| 71 |
+
thread. However, it is possible for `f` not to be called at all, in
|
| 72 |
+
which case its completion never happens. — *end note*]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
|
| 74 |
If the implementation chooses the `launch::async` policy,
|
| 75 |
|
| 76 |
- a call to a waiting function on an asynchronous return object that
|
| 77 |
shares the shared state created by this `async` call shall block until
|
|
|
|
| 81 |
with [[intro.multithread]] the return from the first function that
|
| 82 |
successfully detects the ready status of the shared state or with the
|
| 83 |
return from the last function that releases the shared state,
|
| 84 |
whichever happens first.
|
| 85 |
|
| 86 |
+
*Returns:* An object of type
|
| 87 |
+
`future<invoke_result_t<decay_t<F>, decay_t<Args>...>>` that refers to
|
| 88 |
+
the shared state created by this call to `async`.
|
| 89 |
+
|
| 90 |
+
[*Note 2*: If a future obtained from `async` is moved outside the local
|
| 91 |
+
scope, the future’s destructor can block for the shared state to become
|
| 92 |
+
ready. — *end note*]
|
| 93 |
+
|
| 94 |
*Throws:* `system_error` if `policy == launch::async` and the
|
| 95 |
implementation is unable to start a new thread, or `std::bad_alloc` if
|
| 96 |
+
memory for the internal data structures cannot be allocated.
|
| 97 |
|
| 98 |
*Error conditions:*
|
| 99 |
|
| 100 |
- `resource_unavailable_try_again` — if `policy == launch::async` and
|
| 101 |
the system is unable to start a new thread.
|
| 102 |
|
| 103 |
+
[*Note 1*: Line \#1 might not result in concurrency because the `async`
|
| 104 |
+
call uses the default policy, which might use `launch::deferred`, in
|
| 105 |
+
which case the lambda might not be invoked until the `get()` call; in
|
| 106 |
+
that case, `work1` and `work2` are called on the same thread and there
|
| 107 |
+
is no concurrency. — *end note*]
|
| 108 |
|