<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>N2709 Packaging Tasks for Asynchronous Execution</title>
<meta name="generator" content="DocBook XSL Stylesheets V1.72.0">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table>
  <tr>
    <td align="left">Document Number:</td>
    <td align="left">N2709=08-0219</td>
  </tr>
  <tr>
    <td align="left">Date:</td>
    <td align="left">2008-07-28</td>
  </tr>
  <tr>
    <td align="left">Project:</td>
    <td align="left">Programming Language C++</td>
  </tr>
</table>
<div class="article" lang="en">
<div class="titlepage">
<div>
<div><h2 class="title">
<a name="n2709_packaging_tasks_for_asynchronous_execution"></a>N2709 Packaging Tasks for Asynchronous Execution</h2></div>
<div><div class="authorgroup"><div class="author"><h3 class="author"><a href="mailto:anthony@justsoftwaresolutions.co.uk">
<span class="firstname">Anthony</span> <span class="surname">Williams</span></a>
</h3></div></div></div>
<div><p class="copyright">Copyright  2008 Anthony Williams</p></div>
</div>
<hr>
</div>
<div class="toc">
<p><b>Table of Contents</b></p>
<dl>
<dt><span class="section"><a href="#n2709_packaging_tasks_for_asynchronous_execution.overview">
    Overview</a></span></dt>
<dt><span class="section"><a href="#n2709_packaging_tasks_for_asynchronous_execution.rationale">
    Rationale</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="#n2709_packaging_tasks_for_asynchronous_execution.rationale.spawn_task_pt">
      Spawning a task with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span></code></a></span></dt>
<dt><span class="section"><a href="#n2709_packaging_tasks_for_asynchronous_execution.rationale.spawn_task_promise">
      Spawning a task with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">promise</span></code></a></span></dt>
<dt><span class="section"><a href="#n2709_packaging_tasks_for_asynchronous_execution.rationale.thread_pools">
      Using <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span></code> with thread pools</a></span></dt>
<dt><span class="section"><a href="#n2709_packaging_tasks_for_asynchronous_execution.rationale.single_thread">
      Single-threaded usage</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="#n2709_packaging_tasks_for_asynchronous_execution.reference">
    Proposed Wording</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task">
      <code class="computeroutput"><span class="identifier">packaged_task</span></code> class template</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.task_constructor">
        Task Constructor</a></span></dt>
<dt><span class="section"><a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.move_constructor">
        Move Constructor</a></span></dt>
<dt><span class="section"><a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.move_assignment">
        Move Assignment Operator</a></span></dt>
<dt><span class="section"><a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.destructor">
        Destructor</a></span></dt>
<dt><span class="section"><a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.operator_bool">
        Member Function <code class="computeroutput"><span class="keyword">operator</span> <span class="keyword">bool</span></code></a></span></dt>
<dt><span class="section"><a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.get_future">
        Member Function <code class="computeroutput"><span class="identifier">get_future</span><span class="special">()</span></code></a></span></dt>
<dt><span class="section"><a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.call_operator">
        Member Function <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code></a></span></dt>
<dt><span class="section"><a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.reset">
        Member Function <code class="computeroutput"><span class="identifier">reset</span></code></a></span></dt>
</dl></dd>
</dl></dd>
</dl>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="n2709_packaging_tasks_for_asynchronous_execution.overview"></a><a href="#n2709_packaging_tasks_for_asynchronous_execution.overview" title="Overview">
    Overview</a></h2></div></div></div>
<p>
      This proposal is based on the proposal for <a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task" title="packaged_task class template"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span></code></a>
      in N2561 and N2627. It has been separated from the futures proposal at the
      request of the LWG, and revised in light of LWG comments at the Sophia-Antipolis
      meeting in June 2008.
    </p>
<p>
      A <a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task" title="packaged_task class template"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span></code></a>
      provides a means of binding a function to an asynchronous future values so
      that when the function is invoked, the asynchronous future value becomes populated,
      rather than the return value or exception being propagated to the caller.
    </p>
<p>
      This provides an answer to the perennial question "how do I return a value
      from a thread?": package the function you wish to run as a <a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task" title="packaged_task class template"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span></code></a>
      and pass the packaged task to the thread constructor. The future retrieved
      from the packaged task can then be used to obtain the return value. If the
      function throws an exception, that is stored in the future in place of the
      return value.
    </p>
<pre class="programlisting">
<span class="keyword">int</span> <span class="identifier">calculate_the_answer_to_life_the_universe_and_everything</span><span class="special">()</span>
<span class="special">{</span>
    <span class="keyword">return</span> <span class="number">42</span><span class="special">;</span>
<span class="special">}</span>

<span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">()&gt;</span> <span class="identifier">pt</span><span class="special">(</span><span class="identifier">calculate_the_answer_to_life_the_universe_and_everything</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_future</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">fi</span><span class="special">=</span><span class="identifier">pt</span><span class="special">.</span><span class="identifier">get_future</span><span class="special">();</span>

<span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">task</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">pt</span><span class="special">));</span> <span class="comment">// launch task on a thread
</span>
<span class="identifier">fi</span><span class="special">.</span><span class="identifier">wait</span><span class="special">();</span> <span class="comment">// wait for it to finish
</span>    
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">fi</span><span class="special">.</span><span class="identifier">is_ready</span><span class="special">());</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">fi</span><span class="special">.</span><span class="identifier">has_value</span><span class="special">());</span>
<span class="identifier">assert</span><span class="special">(!</span><span class="identifier">fi</span><span class="special">.</span><span class="identifier">has_exception</span><span class="special">());</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">fi</span><span class="special">.</span><span class="identifier">get_state</span><span class="special">()==</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">future_state</span><span class="special">::</span><span class="identifier">ready</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">fi</span><span class="special">.</span><span class="identifier">get</span><span class="special">()==</span><span class="number">42</span><span class="special">);</span>
</pre>
<p>
      Of course, this is not the only use for <a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task" title="packaged_task class template"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span></code></a>:
      it can be used to store a task for later invocation, much like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">function</span></code>.
    </p>
<p>
      With this revision, <a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task" title="packaged_task class template"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span></code></a>
      has been remodelled to be more in line with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">function</span></code>
      than in N2627: the function call operator now accepts arguments which are passed
      on to the encapsulated function, and the template parameter is a function call
      signature. The key difference is that the result of the function invocation
      is stored in the associated future rather than returned directly to the caller.
    </p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="n2709_packaging_tasks_for_asynchronous_execution.rationale"></a><a href="#n2709_packaging_tasks_for_asynchronous_execution.rationale" title="Rationale">
    Rationale</a></h2></div></div></div>
<p>
      Though <a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task" title="packaged_task class template"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span></code></a>
      doesn't provide any features that can't be built using a combination of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">promise</span></code>
      from N2671 and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">function</span></code>, I believe it to be a common-enough
      usage scenario that it warrants being standardized. In particular, the equivalent
      code using <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">promise</span></code> is cumbersome. For comparison, let's
      look at what's needed to spawn a task on a new thread and retrieve the return
      value in a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_future</span></code>.
    </p>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="n2709_packaging_tasks_for_asynchronous_execution.rationale.spawn_task_pt"></a><a href="#n2709_packaging_tasks_for_asynchronous_execution.rationale.spawn_task_pt" title="Spawning a task with std::packaged_task">
      Spawning a task with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span></code></a></h3></div></div></div>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">F</span><span class="special">&gt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_future</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">()&gt;::</span><span class="identifier">type</span><span class="special">&gt;</span> <span class="identifier">spawn_task</span><span class="special">(</span><span class="identifier">F</span> <span class="identifier">f</span><span class="special">)</span>
<span class="special">{</span>
    <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">()&gt;::</span><span class="identifier">type</span> <span class="identifier">result_type</span><span class="special">;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span><span class="special">&lt;</span><span class="identifier">result_type</span><span class="special">()&gt;</span> <span class="identifier">task</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">f</span><span class="special">));</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_future</span><span class="special">&lt;</span><span class="identifier">result_type</span><span class="special">&gt;</span> <span class="identifier">res</span><span class="special">(</span><span class="identifier">task</span><span class="special">.</span><span class="identifier">get_future</span><span class="special">());</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">task</span><span class="special">));</span>
    <span class="keyword">return</span> <span class="identifier">res</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
        This builds a <a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task" title="packaged_task class template"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span></code></a>
        for the function, obtains a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_future</span></code>
        for the result, moves that task onto a thread (which is automatically detached),
        and returns the future.
      </p>
<p>
        This can easily be extended to handle additional arguments.
      </p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="n2709_packaging_tasks_for_asynchronous_execution.rationale.spawn_task_promise"></a><a href="#n2709_packaging_tasks_for_asynchronous_execution.rationale.spawn_task_promise" title="Spawning a task with std::promise">
      Spawning a task with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">promise</span></code></a></h3></div></div></div>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">F</span><span class="special">&gt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_future</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">()&gt;::</span><span class="identifier">type</span><span class="special">&gt;</span> <span class="identifier">spawn_task</span><span class="special">(</span><span class="identifier">F</span> <span class="identifier">f</span><span class="special">)</span>
<span class="special">{</span>
    <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">()&gt;::</span><span class="identifier">type</span> <span class="identifier">result_type</span><span class="special">;</span>

    <span class="keyword">struct</span> <span class="identifier">local_task</span>
    <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">promise</span><span class="special">&lt;</span><span class="identifier">result_type</span><span class="special">&gt;</span> <span class="identifier">promise</span><span class="special">;</span>
        <span class="identifier">F</span> <span class="identifier">func</span><span class="special">;</span>

        <span class="identifier">local_task</span><span class="special">(</span><span class="identifier">local_task</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)=</span><span class="keyword">delete</span><span class="special">;</span>

        <span class="identifier">local_task</span><span class="special">(</span><span class="identifier">F</span> <span class="identifier">func_</span><span class="special">):</span>
            <span class="identifier">func</span><span class="special">(</span><span class="identifier">func_</span><span class="special">)</span>
        <span class="special">{}</span>

        <span class="identifier">local_task</span><span class="special">(</span><span class="identifier">local_task</span><span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">):</span>
            <span class="identifier">promise</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">other</span><span class="special">.</span><span class="identifier">promise</span><span class="special">)),</span>
            <span class="identifier">f</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">other</span><span class="special">.</span><span class="identifier">f</span><span class="special">))</span>
        <span class="special">{}</span>

        <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()</span>
        <span class="special">{</span>
            <span class="keyword">try</span>
            <span class="special">{</span>
                <span class="identifier">promise</span><span class="special">.</span><span class="identifier">set_value</span><span class="special">(</span><span class="identifier">f</span><span class="special">());</span>
            <span class="special">}</span>
            <span class="keyword">catch</span><span class="special">(...)</span>
            <span class="special">{</span>
                <span class="identifier">promise</span><span class="special">.</span><span class="identifier">set_exception</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">current_exception</span><span class="special">());</span>
            <span class="special">}</span>
        <span class="special">}</span>
    <span class="special">};</span>
    
    <span class="identifier">local_task</span> <span class="identifier">task</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">f</span><span class="special">));</span>

    <span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_future</span><span class="special">&lt;</span><span class="identifier">result_type</span><span class="special">&gt;</span> <span class="identifier">res</span><span class="special">(</span><span class="identifier">task</span><span class="special">.</span><span class="identifier">promise</span><span class="special">.</span><span class="identifier">get_future</span><span class="special">());</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">task</span><span class="special">));</span>
    <span class="keyword">return</span> <span class="identifier">res</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
        <code class="computeroutput"><span class="identifier">local_task</span></code> performs the same
        function as <a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task" title="packaged_task class template"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span></code></a>,
        but in a much more limited manner. It is easy to imagine users getting it
        wrong by forgetting to catch the exception, or creating the promise as a
        local variable and using a lambda as the thread function (and thus getting
        a dangling reference to the promise).
      </p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="n2709_packaging_tasks_for_asynchronous_execution.rationale.thread_pools"></a><a href="#n2709_packaging_tasks_for_asynchronous_execution.rationale.thread_pools" title="Using std::packaged_task with thread pools">
      Using <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span></code> with thread pools</a></h3></div></div></div>
<p>
        <a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task" title="packaged_task class template"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span></code></a>
        is intended to be usable as a basic building block of a thread pool. Whereas
        with <code class="computeroutput"><span class="identifier">spawn_task</span></code> as presented
        above the task is immediately associated with a thread, in a thread pool
        the task could be put on a queue to be executed by a worker thread at a later
        point. The worker threads would then only need to know they were executing
        tasks from the queue, without having to worry about what the functions were,
        or the details of storing the results.
      </p>
<p>
        Advanced thread pool implementations would potentially require access to
        the internals of <a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task" title="packaged_task class template"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span></code></a>
        and/or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_future</span></code>, and would therefore have
        to be provided as part of the same implementation, or require extensions
        to the interfaces. Such extensions are left for a later proposal, as thread
        pools are not being standardized for C++0x.
      </p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="n2709_packaging_tasks_for_asynchronous_execution.rationale.single_thread"></a><a href="#n2709_packaging_tasks_for_asynchronous_execution.rationale.single_thread" title="Single-threaded usage">
      Single-threaded usage</a></h3></div></div></div>
<p>
        Though <a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task" title="packaged_task class template"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span></code></a>
        is ideally suited to multi-threaded usage, it can also be used in a single-threaded
        scenario too. In this case, it is important not to <code class="computeroutput"><span class="identifier">wait</span><span class="special">()</span></code> for the future result, since there isn't
        a background thread to prepare the result, but it does allow an unspecified
        task to be invoked only when necessary.
      </p>
<pre class="programlisting">
<span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span><span class="keyword">int</span><span class="special">)&gt;</span> <span class="identifier">task</span><span class="special">(</span><span class="identifier">create_task</span><span class="special">());</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_future</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">future</span><span class="special">;</span>

<span class="keyword">while</span><span class="special">(!</span><span class="identifier">done</span><span class="special">())</span>
<span class="special">{</span>
    <span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span><span class="identifier">b</span><span class="special">;</span>
    <span class="keyword">if</span><span class="special">(</span><span class="identifier">future_value_needed</span><span class="special">())</span>
    <span class="special">{</span>
        <span class="keyword">if</span><span class="special">(!</span><span class="identifier">future</span><span class="special">.</span><span class="identifier">is_ready</span><span class="special">())</span>
            <span class="identifier">task</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span><span class="identifier">b</span><span class="special">);</span>

        <span class="identifier">do_something</span><span class="special">(</span><span class="identifier">future</span><span class="special">.</span><span class="identifier">get</span><span class="special">());</span>
    <span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
        If the task needs to be invoked multiple times, but should only be invoked
        when necessary, then <a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.reset" title="Member Function reset"><code class="computeroutput"><span class="identifier">reset</span><span class="special">()</span></code></a>
        can be called after the task has been invoked in order to reset the state
        for a subsequent invocation. It is important to note that in this case, a
        fresh <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_future</span></code> must be obtained (by calling
        <a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.get_future" title="Member Function get_future()"><code class="computeroutput"><span class="identifier">get_future</span><span class="special">()</span></code></a>)
        after the call to <a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.reset" title="Member Function reset"><code class="computeroutput"><span class="identifier">reset</span><span class="special">()</span></code></a>:
        any futures already obtained will continue to refer to the result of the
        prior invocation.
      </p>
</div>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="n2709_packaging_tasks_for_asynchronous_execution.reference"></a><a href="#n2709_packaging_tasks_for_asynchronous_execution.reference" title="Proposed Wording">
    Proposed Wording</a></h2></div></div></div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task"></a><a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task" title="packaged_task class template">
      <code class="computeroutput"><span class="identifier">packaged_task</span></code> class template</a></h3></div></div></div>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span><span class="special">&gt;</span> <span class="keyword">class</span> <span class="identifier">packaged_task</span><span class="special">;</span> <span class="comment">// undefined
</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">R</span><span class="special">,</span><span class="keyword">class</span><span class="special">...</span> <span class="identifier">ArgTypes</span><span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">packaged_task</span><span class="special">&lt;</span><span class="identifier">R</span><span class="special">(</span><span class="identifier">ArgTypes</span><span class="special">...)&gt;</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
    <span class="keyword">typedef</span> <span class="identifier">R</span> <span class="identifier">result_type</span><span class="special">;</span>

    <span class="comment">// construction and destruction
</span>    <span class="identifier">packaged_task</span><span class="special">();</span>

    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">&gt;</span>
    <span class="keyword">explicit</span> <span class="identifier">packaged_task</span><span class="special">(</span><span class="identifier">F</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">f</span><span class="special">);</span>

    <span class="keyword">explicit</span> <span class="identifier">packaged_task</span><span class="special">(</span><span class="identifier">R</span><span class="special">(*</span><span class="identifier">f</span><span class="special">)());</span>
    
    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">&gt;</span>
    <span class="keyword">explicit</span> <span class="identifier">packaged_task</span><span class="special">(</span><span class="identifier">F</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">);</span>

    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Allocator</span><span class="special">&gt;</span>
    <span class="keyword">explicit</span> <span class="identifier">packaged_task</span><span class="special">(</span><span class="identifier">allocator_arg_t</span><span class="special">,</span><span class="identifier">Allocator</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">F</span> <span class="identifier">f</span><span class="special">);</span>
    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Allocator</span><span class="special">&gt;</span>
    <span class="keyword">explicit</span> <span class="identifier">packaged_task</span><span class="special">(</span><span class="identifier">allocator_arg_t</span><span class="special">,</span><span class="identifier">Allocator</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">F</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">);</span>

    <span class="special">~</span><span class="identifier">packaged_task</span><span class="special">();</span>

    <span class="comment">// no copy
</span>    <span class="identifier">packaged_task</span><span class="special">(</span><span class="identifier">packaged_task</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
    <span class="identifier">packaged_task</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">packaged_task</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>

    <span class="comment">// move support
</span>    <span class="identifier">packaged_task</span><span class="special">(</span><span class="identifier">packaged_task</span><span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">);</span>
    <span class="identifier">packaged_task</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">packaged_task</span><span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">);</span>

    <span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">packaged_task</span><span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">);</span>

    <span class="keyword">explicit</span> <span class="keyword">operator</span> <span class="keyword">bool</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>

    <span class="comment">// result retrieval
</span>    <span class="identifier">unique_future</span><span class="special">&lt;</span><span class="identifier">R</span><span class="special">&gt;</span> <span class="identifier">get_future</span><span class="special">();</span>        

    <span class="comment">// execution
</span>    <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">ArgTypes</span><span class="special">...</span> <span class="special">);</span>

    <span class="keyword">void</span> <span class="identifier">reset</span><span class="special">();</span>
<span class="special">};</span>
</pre>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.task_constructor"></a><a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.task_constructor" title="Task Constructor">
        Task Constructor</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">F</span><span class="special">&gt;</span>
<span class="identifier">packaged_task</span><span class="special">(</span><span class="identifier">F</span> <span class="keyword">const</span> <span class="special">&amp;</span><span class="identifier">f</span><span class="special">);</span>

<span class="identifier">packaged_task</span><span class="special">(</span><span class="identifier">R</span><span class="special">(*</span><span class="identifier">f</span><span class="special">)());</span>

<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">F</span><span class="special">&gt;</span>
<span class="identifier">packaged_task</span><span class="special">(</span><span class="identifier">F</span><span class="special">&amp;&amp;</span><span class="identifier">f</span><span class="special">);</span>
</pre>
<div class="variablelist">
<p class="title"></p>
<dl>
<dt><span class="term">Preconditions:</span></dt>
<dd><p>
              <code class="computeroutput"><span class="identifier">f</span><span class="special">()</span></code>
              is a valid expression with a return type convertible to <code class="computeroutput"><span class="identifier">R</span></code>. Invoking a copy of <code class="computeroutput"><span class="identifier">f</span></code> shall behave the same as invoking
              <code class="computeroutput"><span class="identifier">f</span></code>.
            </p></dd>
<dt><span class="term">Effects:</span></dt>
<dd><p>
              Constructs a new <a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task" title="packaged_task class template"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span></code></a> with a copy
              of <code class="computeroutput"><span class="identifier">f</span></code> stored as the
              associated task.
            </p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
              Any exceptions thrown by the copy (or move) constructor of <code class="computeroutput"><span class="identifier">f</span></code>. <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>
              if memory for the internal data structures could not be allocated.
            </p></dd>
</dl>
</div>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.move_constructor"></a><a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.move_constructor" title="Move Constructor">
        Move Constructor</a></h4></div></div></div>
<pre class="programlisting">
<span class="identifier">packaged_task</span><span class="special">(</span><span class="identifier">packaged_task</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">);</span>
</pre>
<div class="variablelist">
<p class="title"></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
              Constructs a new <a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task" title="packaged_task class template"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span></code></a>, and transfers
              ownership of the task associated with <code class="computeroutput"><span class="identifier">other</span></code>
              to <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>,
              leaving <code class="computeroutput"><span class="identifier">other</span></code> with
              no associated task.
            </p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
              Nothing.
            </p></dd>
</dl>
</div>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.move_assignment"></a><a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.move_assignment" title="Move Assignment Operator">
        Move Assignment Operator</a></h4></div></div></div>
<pre class="programlisting">
<span class="identifier">packaged_task</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">packaged_task</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">);</span>
</pre>
<div class="variablelist">
<p class="title"></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
              Transfers ownership of the task associated with <code class="computeroutput"><span class="identifier">other</span></code>
              to <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>,
              leaving <code class="computeroutput"><span class="identifier">other</span></code> with
              no associated task. If there was already a task associated with <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>,
              and that task has not been invoked, sets any futures associated with
              that task to <span class="emphasis"><em>ready</em></span> with a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">broken_promise</span></code>
              exception as the result.
            </p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
              Nothing.
            </p></dd>
</dl>
</div>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.destructor"></a><a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.destructor" title="Destructor">
        Destructor</a></h4></div></div></div>
<pre class="programlisting">
<span class="special">~</span><span class="identifier">packaged_task</span><span class="special">();</span>
</pre>
<div class="variablelist">
<p class="title"></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
              Destroys <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
              If there was a task associated with <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>, and that task has not been invoked,
              sets any futures associated with that task to <span class="emphasis"><em>ready</em></span>
              with a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">broken_promise</span></code> exception as the result.
            </p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
              Nothing.
            </p></dd>
</dl>
</div>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.operator_bool"></a><a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.operator_bool" title="Member Function operator bool">
        Member Function <code class="computeroutput"><span class="keyword">operator</span> <span class="keyword">bool</span></code></a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">explicit</span> <span class="keyword">operator</span> <span class="keyword">bool</span><span class="special">()</span> <span class="keyword">const</span>
</pre>
<div class="variablelist">
<p class="title"></p>
<dl>
<dt><span class="term">Returns:</span></dt>
<dd><p>
              <code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
              has an associated task, otherwise <code class="computeroutput"><span class="keyword">false</span></code>.
            </p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
              nothing.
            </p></dd>
</dl>
</div>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.get_future"></a><a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.get_future" title="Member Function get_future()">
        Member Function <code class="computeroutput"><span class="identifier">get_future</span><span class="special">()</span></code></a></h4></div></div></div>
<pre class="programlisting">
<span class="identifier">unique_future</span><span class="special">&lt;</span><span class="identifier">R</span><span class="special">&gt;</span> <span class="identifier">get_future</span><span class="special">();</span>
</pre>
<div class="variablelist">
<p class="title"></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
              Returns a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_future</span></code> associated with the
              result of the task associated with <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
            </p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
              <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_function_call</span></code> if <code class="computeroutput"><span class="special">!*</span><span class="keyword">this</span></code>.
              <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">future_already_retrieved</span></code> if the future
              associated with the task has already been retrieved.
            </p></dd>
</dl>
</div>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.call_operator"></a><a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.call_operator" title="Member Function operator()">
        Member Function <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code></a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">ArgTypes</span><span class="special">...</span> <span class="identifier">args</span><span class="special">);</span>
</pre>
<div class="variablelist">
<p class="title"></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
              <code class="computeroutput"><span class="identifier">INVOKE</span> <span class="special">(</span><span class="identifier">f</span><span class="special">,</span> <span class="identifier">t1</span><span class="special">,</span> <span class="identifier">t2</span><span class="special">,</span> <span class="special">...,</span> <span class="identifier">tN</span><span class="special">,</span> <span class="identifier">R</span><span class="special">)</span></code>, where <code class="computeroutput"><span class="identifier">f</span></code>
              is the task associated with <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> and <code class="computeroutput"><span class="identifier">t1</span></code>,
              <code class="computeroutput"><span class="identifier">t2</span></code>, <code class="computeroutput"><span class="special">...</span></code>,
              <code class="computeroutput"><span class="identifier">tN</span></code> are the values in
              <code class="computeroutput"><span class="identifier">args</span><span class="special">...</span></code>.
              If the task returns normally, the return value is stored as the asynchronous
              result associated with <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>, otherwise the exception thrown
              is stored. Any threads blocked waiting for the asynchronous result
              associated with this task are woken.
            </p></dd>
<dt><span class="term">Postconditions:</span></dt>
<dd><p>
              All futures waiting on the asynchronous result are <span class="emphasis"><em>ready</em></span>
            </p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
              <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_function_call</span></code> if <code class="computeroutput"><span class="special">!*</span><span class="keyword">this</span></code>.
              <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">task_already_started</span></code> if the task
              has already been invoked.
            </p></dd>
</dl>
</div>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.reset"></a><a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.reset" title="Member Function reset">
        Member Function <code class="computeroutput"><span class="identifier">reset</span></code></a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">void</span> <span class="identifier">reset</span><span class="special">();</span>
</pre>
<div class="variablelist">
<p class="title"></p>
<dl>
<dt><span class="term">Effects:</span></dt>
<dd><p>
              Return the task to a state as-if a newly-constructed instance has just
              been assigned to <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
              by <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span><span class="special">=</span><span class="identifier">packaged_task</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">f</span><span class="special">))</span></code> where <code class="computeroutput"><span class="identifier">f</span></code>
              is the task associated with <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>. If there was already a task associated
              with <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>,
              and that task has not been invoked, sets any futures associated with
              that task to <span class="emphasis"><em>ready</em></span> with a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">broken_promise</span></code>
              exception as the result. <a href="#n2709_packaging_tasks_for_asynchronous_execution.reference.packaged_task.get_future" title="Member Function get_future()"><code class="computeroutput"><span class="identifier">get_future</span><span class="special">()</span></code></a>
              may now be called again for <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
            </p></dd>
<dt><span class="term">Postconditions:</span></dt>
<dd><p>
              <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
              has no associated futures. If <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> had an associated task, then the
              associated task is a copy of the old task.
            </p></dd>
<dt><span class="term">Throws:</span></dt>
<dd><p>
              <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code> if memory for the internal
              data structures of the new asynchronous result could not be allocated.
            </p></dd>
</dl>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
