Skip to content

Commit 39612fe

Browse files
committed
Sync_wait return type. Invocability constraints.
1 parent f2a5616 commit 39612fe

File tree

2 files changed

+55
-21
lines changed

2 files changed

+55
-21
lines changed

p1897R3_initial_executor_algorithms_for_cpp23.html

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -806,7 +806,7 @@ <h2 id="executionsync_wait"><span class="header-section-number">3.4</span> execu
806806
<h3 id="overview-2"><span class="header-section-number">3.4.1</span> Overview<a href="#overview-2" class="self-link"></a></h3>
807807
<p>Blocks the calling thread to wait for the passed sender to complete. Returns <code>T</code> when passed a <code>typed_sender</code> that sends a <code>T</code> on the value channel, where <code>T</code> may be <code>void</code>, throws if an exception is propagated and calls <code>std::terminate</code> on propagation of the <code>set_done()</code> signal.</p>
808808
<div class="sourceCode" id="cb14"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1"></a><span class="kw">template</span> <span class="op">&lt;</span>execution<span class="op">::</span>typed_sender S<span class="op">&gt;</span></span>
809-
<span id="cb14-2"><a href="#cb14-2"></a>see<span class="op">-</span>below sync_wait<span class="op">(</span>S<span class="op">&amp;&amp;</span> s<span class="op">)</span>;</span>
809+
<span id="cb14-2"><a href="#cb14-2"></a><span class="kw">auto</span> sync_wait<span class="op">(</span>S<span class="op">&amp;&amp;</span> s<span class="op">)</span> <span class="op">-&gt;</span> std<span class="op">::</span>sender_traits<span class="op">&lt;</span>S<span class="op">&gt;::</span>value_types;</span>
810810
<span id="cb14-3"><a href="#cb14-3"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> ValueType, execution<span class="op">::</span>sender S<span class="op">&gt;</span></span>
811811
<span id="cb14-4"><a href="#cb14-4"></a>ValueType sync_wait_r<span class="op">(</span>S<span class="op">&amp;&amp;</span> s<span class="op">)</span>;</span></code></pre></div>
812812
<p><em>[ Example:</em></p>
@@ -965,10 +965,11 @@ <h2 id="executiontransform"><span class="header-section-number">3.7</span> execu
965965
<h3 id="overview-5"><span class="header-section-number">3.7.1</span> Overview<a href="#overview-5" class="self-link"></a></h3>
966966
<p><code>transform</code> is a sender adapter that takes a <code>sender</code> and an invocable and returns a <code>sender</code> that propagates the value resulting from calling the invocable on the value passed by the preceding <code>sender</code>.</p>
967967
<p>Signature:</p>
968-
<div class="sourceCode" id="cb23"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb23-1"><a href="#cb23-1"></a><span class="kw">template</span> <span class="op">&lt;</span>execution<span class="op">::</span>sender S, std<span class="op">::</span>invocable F<span class="op">&gt;</span></span>
969-
<span id="cb23-2"><a href="#cb23-2"></a>see<span class="op">-</span>below transform<span class="op">(</span>S s, F f<span class="op">)</span>;</span></code></pre></div>
968+
<div class="sourceCode" id="cb23"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb23-1"><a href="#cb23-1"></a><span class="kw">template</span> <span class="op">&lt;</span>execution<span class="op">::</span>sender S, moveable<span class="op">-</span>value F<span class="op">&gt;</span></span>
969+
<span id="cb23-2"><a href="#cb23-2"></a> <span class="kw">requires</span> std<span class="op">::</span>invocable<span class="op">&lt;</span>F, sender_traits<span class="op">&lt;</span>S<span class="op">&gt;::</span><span class="kw">template</span> value_types<span class="op">&gt;</span></span>
970+
<span id="cb23-3"><a href="#cb23-3"></a>see<span class="op">-</span>below transform<span class="op">(</span>S s, F f<span class="op">)</span>;</span></code></pre></div>
970971
<p><em>[ Example:</em></p>
971-
<div class="sourceCode" id="cb24"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb24-1"><a href="#cb24-1"></a>std<span class="op">::</span>optional<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> r <span class="op">=</span> sync_wait<span class="op">(</span>just<span class="op">(</span><span class="dv">3</span><span class="op">)</span> <span class="op">|</span> transform<span class="op">([](</span><span class="dt">int</span> v<span class="op">){</span><span class="cf">return</span> v<span class="op">+</span><span class="dv">1</span>;<span class="op">}))</span>;</span>
972+
<div class="sourceCode" id="cb24"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb24-1"><a href="#cb24-1"></a><span class="dt">int</span> r <span class="op">=</span> sync_wait<span class="op">(</span>just<span class="op">(</span><span class="dv">3</span><span class="op">)</span> <span class="op">|</span> transform<span class="op">([](</span><span class="dt">int</span> v<span class="op">){</span><span class="cf">return</span> v<span class="op">+</span><span class="dv">1</span>;<span class="op">}))</span>;</span>
972973
<span id="cb24-2"><a href="#cb24-2"></a><span class="co">// r==4</span></span></code></pre></div>
973974
<p><em>- end example]</em></p>
974975
<h3 id="wording-5"><span class="header-section-number">3.7.2</span> Wording<a href="#wording-5" class="self-link"></a></h3>
@@ -1043,10 +1044,18 @@ <h2 id="executionlet_error"><span class="header-section-number">3.8</span> execu
10431044
<h3 id="overview-6"><span class="header-section-number">3.8.1</span> Overview<a href="#overview-6" class="self-link"></a></h3>
10441045
<p><code>let_error</code> is a sender adapter that takes a <code>sender</code> and an invocable and returns a <code>sender</code> that, on error propagation, keeps the error result of the incoming sender alive for the duration of the <code>sender</code> returned by the invocable and makes that value available to the invocable.</p>
10451046
<p>Signature:</p>
1046-
<div class="sourceCode" id="cb26"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb26-1"><a href="#cb26-1"></a><span class="kw">template</span> <span class="op">&lt;</span>execution<span class="op">::</span>sender S, std<span class="op">::</span>invocable F<span class="op">&gt;</span></span>
1047-
<span id="cb26-2"><a href="#cb26-2"></a>see<span class="op">-</span>below let_error<span class="op">(</span>S s, F f<span class="op">)</span>;</span></code></pre></div>
1047+
<div class="sourceCode" id="cb26"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb26-1"><a href="#cb26-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">typename</span> F<span class="op">&gt;</span></span>
1048+
<span id="cb26-2"><a href="#cb26-2"></a><span class="kw">struct</span> is<span class="op">-</span>invocable<span class="op">-</span>with <span class="op">{</span></span>
1049+
<span id="cb26-3"><a href="#cb26-3"></a> <span class="kw">template</span><span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
1050+
<span id="cb26-4"><a href="#cb26-4"></a> <span class="kw">using</span> apply <span class="op">=</span> std<span class="op">::</span>bool_constant<span class="op">&lt;(</span>std<span class="op">::</span>invocable<span class="op">&lt;</span>F, Args<span class="op">...&gt;</span> <span class="op">&amp;&amp;</span> <span class="op">...)&gt;</span>;</span>
1051+
<span id="cb26-5"><a href="#cb26-5"></a><span class="op">}</span>;</span>
1052+
<span id="cb26-6"><a href="#cb26-6"></a></span>
1053+
<span id="cb26-7"><a href="#cb26-7"></a><span class="kw">template</span><span class="op">&lt;</span>execution<span class="op">::</span>sender S, moveable<span class="op">-</span>value F<span class="op">&gt;</span></span>
1054+
<span id="cb26-8"><a href="#cb26-8"></a> <span class="kw">requires</span> sender_traits<span class="op">&lt;</span>S<span class="op">&gt;::</span><span class="kw">template</span> error_types<span class="op">&lt;</span></span>
1055+
<span id="cb26-9"><a href="#cb26-9"></a> is<span class="op">-</span>invocable<span class="op">-</span>with<span class="op">&lt;</span>F<span class="op">&gt;::</span><span class="kw">template</span> apply<span class="op">&gt;::</span>value</span>
1056+
<span id="cb26-10"><a href="#cb26-10"></a>see<span class="op">-</span>below let_error<span class="op">(</span>S s, F f<span class="op">)</span>;</span></code></pre></div>
10481057
<p><em>[ Example:</em></p>
1049-
<div class="sourceCode" id="cb27"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb27-1"><a href="#cb27-1"></a>std<span class="op">::</span>optional<span class="op">&lt;</span><span class="dt">float</span><span class="op">&gt;</span> r <span class="op">=</span> sync_wait<span class="op">(</span></span>
1058+
<div class="sourceCode" id="cb27"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb27-1"><a href="#cb27-1"></a><span class="dt">float</span> r <span class="op">=</span> sync_wait<span class="op">(</span></span>
10501059
<span id="cb27-2"><a href="#cb27-2"></a> just<span class="op">(</span><span class="dv">3</span><span class="op">)</span> <span class="op">|</span></span>
10511060
<span id="cb27-3"><a href="#cb27-3"></a> transform<span class="op">([](</span><span class="dt">int</span> v<span class="op">){</span><span class="cf">throw</span> <span class="fl">2.0</span><span class="bu">f</span>;<span class="op">})</span> <span class="op">|</span></span>
10521061
<span id="cb27-4"><a href="#cb27-4"></a> let_error<span class="op">([](</span><span class="dt">float</span> e<span class="op">){</span><span class="cf">return</span> just<span class="op">(</span>e<span class="op">+</span><span class="dv">1</span><span class="op">)</span>;<span class="op">}))</span>;</span>
@@ -1089,7 +1098,7 @@ <h3 id="overview-7"><span class="header-section-number">3.9.1</span> Overview<a
10891098
<div class="sourceCode" id="cb30"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb30-1"><a href="#cb30-1"></a><span class="kw">auto</span> s1 <span class="op">=</span> just<span class="op">(</span><span class="dv">3</span><span class="op">)</span> <span class="op">|</span> share<span class="op">()</span>;</span>
10901099
<span id="cb30-2"><a href="#cb30-2"></a><span class="kw">auto</span> s2 <span class="op">=</span> s1 <span class="op">|</span> transform<span class="op">([](</span><span class="kw">const</span> <span class="dt">int</span><span class="op">&amp;</span> v<span class="op">){</span><span class="cf">return</span> v<span class="op">+</span><span class="dv">1</span>;<span class="op">}))</span></span>
10911100
<span id="cb30-3"><a href="#cb30-3"></a><span class="kw">auto</span> s3 <span class="op">=</span> s1 <span class="op">|</span> transform<span class="op">([](</span><span class="kw">const</span> <span class="dt">int</span><span class="op">&amp;</span> v<span class="op">){</span><span class="cf">return</span> v<span class="op">+</span><span class="dv">2</span>;<span class="op">}))</span></span>
1092-
<span id="cb30-4"><a href="#cb30-4"></a>std<span class="op">::</span>optional<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> r <span class="op">=</span> sync_wait<span class="op">(</span></span>
1101+
<span id="cb30-4"><a href="#cb30-4"></a><span class="dt">int</span> r <span class="op">=</span> sync_wait<span class="op">(</span></span>
10931102
<span id="cb30-5"><a href="#cb30-5"></a> transform<span class="op">(</span></span>
10941103
<span id="cb30-6"><a href="#cb30-6"></a> when_all<span class="op">(</span>s2, s3<span class="op">)</span>,</span>
10951104
<span id="cb30-7"><a href="#cb30-7"></a> <span class="op">[](</span><span class="dt">int</span> a, <span class="dt">int</span> b<span class="op">){</span><span class="cf">return</span> a<span class="op">+</span>b;<span class="op">}))</span>;</span>
@@ -1121,11 +1130,19 @@ <h2 id="executionlet_value"><span class="header-section-number">3.10</span> exec
11211130
<h3 id="overview-8"><span class="header-section-number">3.10.1</span> Overview<a href="#overview-8" class="self-link"></a></h3>
11221131
<p><code>let_value</code> is a sender adapter that takes a <code>sender</code> and an invocable and returns a <code>sender</code> that keeps the completion result of the incoming sender alive for the duration of the algorithm returned by the invocable and makes that value available to the invocable.</p>
11231132
<p>Signature:</p>
1124-
<div class="sourceCode" id="cb32"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb32-1"><a href="#cb32-1"></a><span class="kw">template</span> <span class="op">&lt;</span>execution<span class="op">::</span>sender S, std<span class="op">::</span>invocable F<span class="op">&gt;</span></span>
1125-
<span id="cb32-2"><a href="#cb32-2"></a>see<span class="op">-</span>below let_value<span class="op">(</span>S s, F f<span class="op">)</span>;</span></code></pre></div>
1133+
<div class="sourceCode" id="cb32"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb32-1"><a href="#cb32-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">typename</span> F<span class="op">&gt;</span></span>
1134+
<span id="cb32-2"><a href="#cb32-2"></a><span class="kw">struct</span> is<span class="op">-</span>invocable<span class="op">-</span>with <span class="op">{</span></span>
1135+
<span id="cb32-3"><a href="#cb32-3"></a> <span class="kw">template</span><span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> Args<span class="op">&gt;</span></span>
1136+
<span id="cb32-4"><a href="#cb32-4"></a> <span class="kw">using</span> apply <span class="op">=</span> std<span class="op">::</span>bool_constant<span class="op">&lt;(</span>std<span class="op">::</span>invocable<span class="op">&lt;</span>F, Args<span class="op">...&gt;</span> <span class="op">&amp;&amp;</span> <span class="op">...)&gt;</span>;</span>
1137+
<span id="cb32-5"><a href="#cb32-5"></a><span class="op">}</span>;</span>
1138+
<span id="cb32-6"><a href="#cb32-6"></a></span>
1139+
<span id="cb32-7"><a href="#cb32-7"></a><span class="kw">template</span><span class="op">&lt;</span>execution<span class="op">::</span>sender S, moveable<span class="op">-</span>value F<span class="op">&gt;</span></span>
1140+
<span id="cb32-8"><a href="#cb32-8"></a> <span class="kw">requires</span> sender_traits<span class="op">&lt;</span>S<span class="op">&gt;::</span><span class="kw">template</span> value_types<span class="op">&lt;</span></span>
1141+
<span id="cb32-9"><a href="#cb32-9"></a> is<span class="op">-</span>invocable<span class="op">-</span>with<span class="op">&lt;</span>F<span class="op">&gt;::</span><span class="kw">template</span> apply<span class="op">&gt;::</span>value</span>
1142+
<span id="cb32-10"><a href="#cb32-10"></a>see<span class="op">-</span>below let_value<span class="op">(</span>S s, F f<span class="op">)</span>;</span></code></pre></div>
11261143
<p>where <code>S&lt;T...&gt;</code> and <code>S&lt;T2&gt;</code> are implementation-defined types that is represent senders that send a value of type list <code>T...</code> or <code>T2</code> respectively in their value channels. Note that in the general case there may be many types <code>T...</code> for a given <code>sender</code>, in which case the invocable may have to represent an overload set.</p>
11271144
<p><em>[ Example:</em></p>
1128-
<div class="sourceCode" id="cb33"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb33-1"><a href="#cb33-1"></a>std<span class="op">::</span>optional<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> r <span class="op">=</span> sync_wait<span class="op">(</span></span>
1145+
<div class="sourceCode" id="cb33"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb33-1"><a href="#cb33-1"></a><span class="dt">int</span> r <span class="op">=</span> sync_wait<span class="op">(</span></span>
11291146
<span id="cb33-2"><a href="#cb33-2"></a> just<span class="op">(</span><span class="dv">3</span><span class="op">)</span> <span class="op">|</span></span>
11301147
<span id="cb33-3"><a href="#cb33-3"></a> let_value<span class="op">([](</span><span class="dt">int</span><span class="op">&amp;</span> let_v<span class="op">){</span></span>
11311148
<span id="cb33-4"><a href="#cb33-4"></a> <span class="cf">return</span> just<span class="op">(</span><span class="dv">4</span><span class="op">)</span> <span class="op">|</span> transform<span class="op">([&amp;](</span><span class="dt">int</span> v<span class="op">){</span><span class="cf">return</span> let_v <span class="op">+</span> v;<span class="op">})))</span>;</span>
@@ -1161,7 +1178,7 @@ <h1 id="customization-and-example"><span class="header-section-number">4</span>
11611178
<span id="cb35-4"><a href="#cb35-4"></a> transform([](int a){return a*2;}) | // s4</span>
11621179
<span id="cb35-5"><a href="#cb35-5"></a> on(scheduler2) | // s5</span>
11631180
<span id="cb35-6"><a href="#cb35-6"></a> let_error([](auto e){return just(3);}); // s6</span>
1164-
<span id="cb35-7"><a href="#cb35-7"></a>std::optional&lt;int&gt; r = sync_wait(s);</span></code></pre></div>
1181+
<span id="cb35-7"><a href="#cb35-7"></a>int r = sync_wait(s);</span></code></pre></div>
11651182
<p>The result of <code>s1</code> might be a <code>just_sender&lt;int&gt;</code> implemented by the standard library vendor.</p>
11661183
<p><code>on(just_sender&lt;int&gt;, scheduler1)</code> has no customization defined, and this expression returns an <code>scheduler1_on_sender&lt;int&gt;</code> that is a custom type from the author of <code>scheduler1</code>, it will call <code>submit</code> on the result of <code>s1</code>.</p>
11671184
<p><code>s3</code> calls <code>transform(scheduler1_on_sender&lt;int&gt;, [](int a){return a+1;})</code> for which the author of <code>scheduler1</code> may have written a customization. The <code>scheduler1_on_sender</code> has stashed the value somewhere and build some work queue in the background. We do not see <code>submit</code> called at this point, it uses a behind-the-scenes implementation to schedule the work on the work queue. An <code>scheduler1_transform_sender&lt;int&gt;</code> is returned.</p>

0 commit comments

Comments
 (0)