From Jason Turner

[futures.async]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpsvtgkt5o/{from.md → to.md} +38 -37
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
- *Requires:* `F` and each `Ti` in `Args` shall satisfy the
17
- `MoveConstructible` requirements, and
18
 
19
- ``` cpp
20
- INVOKE(DECAY_COPY(std::forward<F>(f)),
21
- DECAY_COPY(std::forward<Args>(args))...) // see [func.require] [thread.thread.constr]
22
- ```
 
23
 
24
- shall be a valid expression.
 
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
- *INVOKE*(*DECAY_COPY*(std::forward\<F\>(f)),
36
- *DECAY_COPY*(std::forward\<Args\>(args))...) ([[func.require]],
37
  [[thread.thread.constr]]) as if in a new thread of execution
38
- represented by a `thread` object with the calls to *DECAY_COPY*()
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 *INVOKE*(*DECAY_COPY*(std::forward\<F\>(f)),
42
- *DECAY_COPY*(std::forward\<Args\>(args))...) is stored as the
43
- exceptional result in the shared state. The `thread` object is stored
44
- in the shared state and affects the behavior of any asynchronous
45
- return objects that reference that state.
46
  - If `launch::deferred` is set in `policy`, stores
47
- *DECAY_COPY*(std::forward\<F\>(f)) and
48
- *DECAY_COPY*(std::forward\<Args\>(args))... in the shared state. These
49
  copies of `f` and `args` constitute a *deferred function*. Invocation
50
- of the deferred function evaluates *INVOKE*(std::move(g),
51
- std::move(xyz)) where `g` is the stored value of
52
- *DECAY_COPY*(std::forward\<F\>(f)) and `xyz` is the stored copy of
53
- *DECAY_COPY*(std::forward\<Args\>(args)).... Any return value is
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 ([[futures.state]]) on an asynchronous return object
59
- referring to this shared state shall invoke the deferred function in
60
- the thread that called the waiting function. Once evaluation of
61
- *INVOKE*(std::move(g), std::move(xyz)) begins, the function is no
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 International Standard nor by the
69
- implementation, the behavior is undefined.
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 must be aware that the future’s
77
- destructor may block for the shared state to become
78
  ready. — *end note*]
79
 
80
  *Synchronization:* Regardless of the provided `policy` argument,
81
 
82
- - the invocation of `async` synchronizes with ([[intro.multithread]])
83
- the invocation of `f`. \[*Note 2*: This statement applies even when
84
- the corresponding `future` object is moved to another
85
  thread. — *end note*] ; and
86
  - the completion of the function `f` is sequenced
87
- before ([[intro.multithread]]) the shared state is made ready.
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 ([[thread.thread.member]]);
97
  - the associated thread completion synchronizes
98
- with ([[intro.multithread]]) the return from the first function that
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