
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
    "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta charset="utf-8">
<title>Add parameter preview to coroutine promise constructor</title>
<style type="text/css">
  p {text-align:justify}
  li {text-align:justify}
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table {border-collapse: collapse;}
  table, th, td {
    border: 1px solid black;
    border-collapse: collapse;
  }
  
  .docinfo { float: right }
  .docinfo p { margin: 0; text-align:right; }
  .docinfo address { font-style: normal; }
</style>
</head>
<body>
<!--
<div class="docinfo">
    <p>ISO/IEC JTC1 SC22 WG21 D00914r0</p>
    <p>Date: 2018-02-08</p>
    <p>Audience: Evolution</p>
    <address>
      GorNishanov &lt;<a href="mailto:gorn@microsoft.com">gorn@microsoft.com</a>&gt;
    </address>
</div>
-->
<table>
<tr>
<td align="left">Doc. no.</td>
<td align="left">P0914r0</td>
</tr>
<!--<tr>
<td align="left">Revises</td>
<td align="left">P0664R1</td>
</tr>
-->
<tr>
<td align="left">Date:</td>
<td align="left">2018-02-08 at 14:25:00 UTC
</td>
</tr>
<!--
<tr>
<td align="left">Project:</td>
<td align="left">Programming Language C++</td>
</tr>
-->
<tr>
<td align="left">Reference:</td>
<td align="left">ISO/IEC TS 22277, C++ Extensions for Coroutines</td>
</tr>
<tr>
<td align="left">Audience:</td>
<td align="left">EWG</td>
</tr>
<tr>
<td align="left">Reply to:</td>
<td align="left">Gor Nishanov &lt;<a href="mailto:gorn@microsoft.com">gorn@microsoft.com</a>&gt;</td>
</tr>
</table>
<h1>Add parameter preview to coroutine promise constructor</h1>
<h2> Issue </h2>
<!--
<p>All proposed resolutions wording is relative to <a href="https://isocpp.org/files/papers/N4680.pdf">N4680</a> (ISO/IEC TS 22277).</p>

<p><b>Section:</b> 8.4.4 [dcl.fct.def.coroutine] <b>Status:</b> Has wording
 <b>Submitter:</b> Eric Niebler <b>Opened:</b> 2018-02-08 <b>Last modified:</b> 2018-02-08</p>
<p><b>Issue:</b></p>
-->
<p>
  Users of C++ coroutines have long been requesting an ability to access coroutine parameters 
  in the constructor of the coroutine promise. Current workaround is to override 
  <code>operator new</code> of the coroutine promise that does allow observing of 
  coroutine parameters, then extract the value of the desired parameter and store it in 
  a <code>thread_local</code> variable and later extract the value
  from the <code>thread_local</code> in the coroutine promise default constructor and 
  store the value in the coroutine promise.
</p>
<p>
  The workaround used is not reliable as compiler is allowed to elide heap allocation for the coroutine
  state and elide invocation of <code>operator new</code>. Coroutines need direct and reliable way of 
  expressing the desired behavior.
</p>
<p>
  Suggestion is to give a coroutine promise an ability to look at the coroutine parameters.
</p>
<p><b>Before:</b></p>
<pre>
  struct my_promise_type {
    static thread_local cancellation_token saved_tok;
    cancellation_token tok;

    template &lt;typename... Whatever&gt;
    void* operator new(size_t sz, cancellation_token tok, Whatever const&...) {
      // BROKEN: May not get called if heap allocation is elided.
      saved_tok = tok;
      return ::operator new(sz);
    }

    my_promise_type() : tok(saved_tok) {}
    ...
  };
</pre>
  <p><b>After:</b></p>
<pre>
  struct my_promise_type {
    cancellation_token tok;

    template &lt;typename... Whatever&gt;
    my_promise_type(cancellation_token tok, Whatever const&) : tok(tok) {}
    ...
  };
</pre>
    
<h2>Wording:</h2>
<p><i>[Proposed wording is relative to <a href="https://isocpp.org/files/papers/N4680.pdf">N4680</a> (ISO/IEC TS 22277)].</i></p>

<p>Modify paragraph 8.4.4/3 as follows:</p>
<blockquote>
    <pre>
        {
          <i>P p</i><ins> <i>promise-constructor-arguments<sub>opt</sub></i></ins>;
          co_await <i>p</i>.initial_suspend(); <i>// initial suspend point</i>
          try {
            F 
          } catch(...) { <i>p</i>.unhandled_exception(); }
        <i>final_suspend</i>:
          co_await <i>p</i>.final_suspend(); <i></i>// final suspend point</i>
        }  
      </pre>
      where an object denoted as <i>p</i> is the promise object of the coroutine<ins>,</ins> 
      <del>and</del> its type <i>P</i> is the <i>promise type</i> of the coroutine<ins>, 
      and <i>promise-constructor-arguments<sub>opt</sub></i>
      is determined as follows:
      Overload resolution is performed on a promise constructor call created by 
      assembling an argument list with lvalues <i>p</i><sub>1</sub> ... <i>p</i><sub>n</sub>.
      If matching constructor is found, then <i>promise-constructor-arguments<sub>opt</sub></i>
      is <code>(<i>p</i><sub>1</sub> ... <i>p</i><sub>n</sub>)</code>, otherwise <i>promise-constructor-arguments<sub>opt</sub></i>
      is nothing</ins>.
</blockquote>

<p>Add underlined text to 8.4.4/11:<p>
  <blockquote>
    When a coroutine is invoked, a copy is created for each coroutine parameter. Each such copy
    is an object with automatic storage duration that is direct-initialized from an lvalue referring to
    11
    the corresponding parameter if the parameter is an lvalue reference, and from an xvalue referring
    to it otherwise. A reference to a parameter in the function-body of the coroutine <ins>and in the call 
    to coroutine promise constructor</ins> is replaced by
    a reference to its copy.
  </blockquote>

<h2>Implementation experience</h2>

Implemented in clang trunk.

<!--
<h2>Use cases and history</h2>

<h3> Cancellation </h3>
<pre>
  task&lt;int&gt;(cancellation_token tok) {
    ...
    int i = co_await foo(); // will cancel if tok is signalled
  }
</pre>

<h3> Altering execution context </h3>
<pre>
  task&lt;int&gt;(execution_context ex) {
    ...
    int i = co_await foo(); // continuations will be invoked in a different execution context.
  }
</pre>
-->
</body>
</html>
