Skip to content

Commit dbc2574

Browse files
committed
Incorporate fix for 4466 into P/R for 4339
1 parent bfb294e commit dbc2574

File tree

2 files changed

+88
-2
lines changed

2 files changed

+88
-2
lines changed

xml/issue4339.xml

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,92 @@ use `std::move` on `*st.result`.
6060
LWG <iref ref="4415"/> renames `uncaught_exception` to `unhandled_exception`.
6161
</p>
6262

63+
<superseded>
64+
<p>
65+
In <sref ref="[task.state]"/>, add
66+
exposition-only data members <code><i>result</i></code> and
67+
<code><i>error</i></code> to the exposition-only class
68+
<code><i>state</i></code>:
69+
<blockquote>
70+
<pre>
71+
namespace std::execution {
72+
template&lt;class T, class Environment&gt;
73+
template&lt;receiver Rcvr&gt;
74+
class task&lt;T, Environment&gt;::<i>state</i> { // <i>exposition only</i>
75+
...
76+
Environment <i>environment</i>; // <i>exposition only</i>
77+
<ins>optional&lt;T&gt; <i>result</i>; // <i>exposition only; present only if</i> is_void_v&lt;T&gt; <i>is</i> false</ins>
78+
<ins>exception_ptr <i>error</i>; // <i>exposition-only</i></ins>
79+
};
80+
}
81+
</pre>
82+
</blockquote>
83+
</p>
84+
<p>
85+
Remove the exposition-only data members
86+
<code><i>result</i></code> and <code><i>errors</i></code> from
87+
the class <code>promise_type</code> in
88+
<sref ref="[task.promise]"/>:
89+
<blockquote>
90+
<pre>
91+
namespace std::execution {
92+
template&lt;class T, class Environment&gt;
93+
class task&lt;T, Environment&gt;::promise_type {
94+
...
95+
stop_token_type <i>token</i>; // <i>exposition only</i>
96+
<del>optional&lt;T&gt; <i>result</i>; // <i>exposition only; present only if</i> is_void_v&lt;T&gt; <i>is</i> false</del>
97+
<del><i>error-variant</i> <i>errors</i>; // <i>exposition only</i></del>
98+
};
99+
}
100+
</pre>
101+
</blockquote>
102+
</p>
103+
<p>
104+
The definition of <code><i>error-variant</i></code> isn't needed, i.e., remove <sref ref="[task.promise]"/> paragraph 2:
105+
<blockquote>
106+
<p><del>
107+
-2- <code><i>error-variant</i></code> is a <code>variant&lt;monostate, remove_cvref_t&lt;E&gt;...&gt;</code>, with duplicate types removed, where <code>E...</code> are template arguments of the specialization of <code>execution::completion_signatures</code> denoted by <code>error_types</code>.
108+
</del></p>
109+
</blockquote>
110+
</p>
111+
<p>
112+
In <sref ref="[task.promise]"/> change paragraph 7 to use the members added to <code><i>state</i></code>:
113+
<blockquote>
114+
<pre>auto final_suspend() noexcept</pre>
115+
<p>-7- <i>Returns</i>: An awaitable object of unspecified type (<sref ref="[expr.await]"/>) whose member functions arrange for the completion of the asynchronous operation associated with <code><i>STATE</i>(*this)</code><del> by invoking</del><ins>. Let <code>st</code> be a reference to <code><i>STATE</i>(*this)</code>. The asynchronous completion first destroys the coroutine frame using <code>st.<i>handle</i>.destroy()</code> and then invokes</ins>:</p>
116+
117+
<ul>
118+
<li>-7.1- <code>set_error(std::move(<del><i>RCVR</i>(*this)</del><ins>st.<i>rcvr</i></ins>), std::move(<del>e</del><ins>st.<i>error</i></ins>))</code> if <del><code><i>errors</i>.index()</code> is greater than zero and <code>e</code> is the value held by <code><i>errors</i></code></del><ins><code>bool(st.<i>error</i>)</code> is <code>true</code></ins>, otherwise</li>
119+
<li>-7.2- <code>set_value(std::move(<del><i>RCVR</i>(*this)</del><ins>st.<i>rcvr</i></ins>))</code> if <code>is_void&lt;T&gt;</code> is <code>true</code>, and otherwise</li>
120+
<li>-7.3- <code>set_value(std::move(<del><i>RCVR</i>(*this)</del><ins>st.<i>rcvr</i></ins>), *<ins>st.</ins><i>result</i>)</code>.</li>
121+
</ul>
122+
</blockquote>
123+
</p>
124+
<p>
125+
Change the specification of <code>yield_value</code> to destroy the coroutine frame before invoking the <code>set_error</code> completion, i.e., change <sref ref="[task.promise]"/> paragraph 9:
126+
<blockquote>
127+
<p>-9- <i>Returns</i>: An awaitable object of unspecified type ([expr.await]) whose member functions arrange for the calling coroutine to be suspended and then completes the asynchronous operation associated with <code><i>STATE</i>(*this)</code><del> by</del><ins>. Let <code>st</code> be a reference to <code><i>STATE</i>(*this)</code>. Then the asynchronous operation completes by first destroying the coroutine frame using <code>st.<i>handle</i>.destroy()</code> and then</ins> invoking <code>set_error(std::move(<del><i>RCVR</i>(*this)</del><ins>st.<i>rcvr</i></ins>), Cerr(std::move(err.error)))</code>.
128+
</p>
129+
</blockquote>
130+
</p>
131+
<p>
132+
Change the specification of <code>unhandled_stopped</code> to destroy the coroutine frame before invoking the <code>set_stopped</code> completion, i.e., change <sref ref="[task.promise]"/> paragraph 13:
133+
<blockquote>
134+
<pre>coroutine_handle&lt;&gt; unhandled_stopped();</pre>
135+
<p>-13- <i>Effects</i>: Completes the asynchronous operation associated with <code><i>STATE</i>(*this)</code><del> by</del><ins>. Let <code>st</code> be a reference to <code><i>STATE</i>(*this)</code>. The asynchronous operation is completed by first destroying the coroutine frame using <code>st.<i>handle</i>.destroy()</code> and then</ins> invoking <code>set_stopped(std::move(<del><i>RCVR</i>(*this)</del><ins>st.<i>rcvr</i></ins>))</code>.</p>
136+
</blockquote>
137+
</p>
138+
</superseded>
139+
140+
<note>2025-11-07; Jonathan provides improved wording</note>
141+
<p>
142+
Incorporate change from LWG <iref ref="4466"/> and add `_v` to `is_void`.
143+
</p>
144+
63145
</discussion>
64146

65147
<resolution>
148+
66149
<p>
67150
In <sref ref="[task.state]"/>, add
68151
exposition-only data members <code><i>result</i></code> and
@@ -118,8 +201,8 @@ In <sref ref="[task.promise]"/> change paragraph 7 to use the members added to <
118201

119202
<ul>
120203
<li>-7.1- <code>set_error(std::move(<del><i>RCVR</i>(*this)</del><ins>st.<i>rcvr</i></ins>), std::move(<del>e</del><ins>st.<i>error</i></ins>))</code> if <del><code><i>errors</i>.index()</code> is greater than zero and <code>e</code> is the value held by <code><i>errors</i></code></del><ins><code>bool(st.<i>error</i>)</code> is <code>true</code></ins>, otherwise</li>
121-
<li>-7.2- <code>set_value(std::move(<del><i>RCVR</i>(*this)</del><ins>st.<i>rcvr</i></ins>))</code> if <code>is_void&lt;T&gt;</code> is <code>true</code>, and otherwise</li>
122-
<li>-7.3- <code>set_value(std::move(<del><i>RCVR</i>(*this)</del><ins>st.<i>rcvr</i></ins>), *<ins>st.</ins><i>result</i>)</code>.</li>
204+
<li>-7.2- <code>set_value(std::move(<del><i>RCVR</i>(*this)</del><ins>st.<i>rcvr</i></ins>))</code> if <code>is_void<ins>_v</ins>&lt;T&gt;</code> is <code>true</code>, and otherwise</li>
205+
<li>-7.3- <code>set_value(std::move(<del><i>RCVR</i>(*this)</del><ins>st.<i>rcvr</i></ins>), *<ins>std::move(st.</ins><i>result</i><ins>)</ins>)</code>.</li>
123206
</ul>
124207
</blockquote>
125208
</p>

xml/issue4466.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ Resolution would be to change the bullet (7.3) to:
2828
<blockquote><pre>
2929
set_value(std::move(<i>RCVR</i>(*this)), *<ins>std::move(</ins><i>result</i><ins>)</ins>).
3030
</pre></blockquote>
31+
32+
<note>2025-11-07; This would be resolved by LWG <iref ref="4339"/>.</note>
33+
3134
</discussion>
3235

3336
<resolution>

0 commit comments

Comments
 (0)