<html><head>
<style>
body { font-family: "Book Antiqua", "Times New Roman", "Times", serif; padding: 2em; }
.programlisting, .computeroutput, .literal { font-family: "Consolas", monospace; font-size: 90%; }
blockquote pre.programlisting { margin-left: 1em; padding-left: 1em; }
div.table { text-align: center; }
.sidebar { background-color: #e0e0e0; font-style: italic; }
p { text-align: justify; }
p.tablecaption { font-weight: bold; text-align: center; }
p.title { font-weight: bold; text-align: center; }
div.section { position: relative; }
span.xrefid { position: absolute; right: 0em; top: 0em; }
table { margin: auto; border: 1px solid gray; border-collapse: collapse; }
th { border: 1px solid gray; padding: 0.5em; }
td { border: 1px solid gray; padding: 0.5em; }
h1, h2, h3, h4, h5, div.titlepage { page-break-after: avoid; }
dl { margin-top: 0px; margin-bottom: 0px; }
</style>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"><title>Executors and Asynchronous Operations, Revision 2</title><meta name="generator" content="DocBook XSL Stylesheets V1.75.2"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<pre>Doc. no:  P0113R0 
Date:     2015-09-25
Revises:  N4242
Reply-To: Christopher Kohlhoff &lt;chris@kohlhoff.com&gt;
</pre>
<div class="chapter" title="Executors and Asynchronous Operations, Revision 2"><div class="titlepage"><div><div><h2 class="title"><a name="executors"></a>Executors and Asynchronous Operations, Revision 2</h2></div></div></div><div class="section" title="1.&#160;Introduction"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="executors.introduction"></a>1.&#160;Introduction</h2></div></div></div><p>
      This proposal describes an executors design that uses a lightweight, template-based
      policy approach. To describe the approach in a nutshell:
    </p><div class="blockquote"><blockquote class="blockquote"><p>
        <span class="emphasis"><em>An executor is to function execution as an allocator is to allocation.</em></span>
      </p></blockquote></div><p>
      This proposal is the asynchronous model that underpins the P0112R0 Networking
      Library proposal, and the proposed wording below is taken from the corresponding
      sections of P0112R0. In doing so, it takes design concepts from Boost.Asio,
      many of which have been unchanged since its inclusion in Boost, and repackages
      them in a way that is more suited to C++14 language facilities.
    </p></div><div class="section" title="2.&#160;Changes in this revision"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="executors.changes_in_this_revision"></a>2.&#160;Changes in this revision</h2></div></div></div><p>
      In this revision, the proposal has been updated to include only those facilities
      required by P0112 Networking Library, plus the two classes <code class="computeroutput"><span class="identifier">thread_pool</span></code>
      and <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>. In particular,
      this revision incorporates design and wording changes resulting from the LWG
      wording review in Cologne and the LEWG design review in Lenexa.
    </p></div><div class="section" title="3.&#160;Reference implementation"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="executors.reference_implementation"></a>3.&#160;Reference implementation</h2></div></div></div><p>
      A standalone reference implementation of the proposed library can be found
      at <span class="emphasis"><em><a href="http://github.com/chriskohlhoff/executors/tree/v0.2-branch" target="_top">http://github.com/chriskohlhoff/executors/tree/v0.2-branch</a></em></span>.
      This implementation requires a C++14 compiler.
    </p><p>
      To better illustrate how the executors library interacts with asynchronous
      operations, and to allow the facility to be used in production code, an almost
      complete implementation of the proposal text may be found in the variant of
      Asio that stands alone from Boost. This variant is available at <span class="emphasis"><em><a href="https://github.com/chriskohlhoff/asio/tree/master" target="_top">https://github.com/chriskohlhoff/asio/tree/master</a></em></span>.
    </p></div><div class="section" title="4.&#160;A two minute introduction to the library"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="executors.a_two_minute_introduction_to_the_library"></a>4.&#160;A two minute introduction to the library</h2></div></div></div><p>
      Run a function asynchronously:
    </p><pre class="programlisting"><span class="identifier">post</span><span class="special">([]{</span>
    <span class="comment">// ...</span>
  <span class="special">});</span>
</pre><p>
      Run a function asynchronously, on your own thread pool:
    </p><pre class="programlisting"><span class="identifier">thread_pool</span> <span class="identifier">pool</span><span class="special">;</span>

<span class="identifier">post</span><span class="special">(</span><span class="identifier">pool</span><span class="special">,</span> <span class="special">[]{</span>
    <span class="comment">// ...</span>
  <span class="special">});</span>

<span class="identifier">pool</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span>
</pre><p>
      Run a function asynchronously and wait for the result:
    </p><pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">f</span> <span class="special">=</span>
  <span class="identifier">post</span><span class="special">(</span><span class="identifier">use_future</span><span class="special">([]{</span>
    <span class="comment">// ...</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">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
</pre><p>
      Run a function asynchronously, on your own thread pool, and wait for the result:
    </p><pre class="programlisting"><span class="identifier">thread_pool</span> <span class="identifier">pool</span><span class="special">;</span>

<span class="identifier">std</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">f</span> <span class="special">=</span>
  <span class="identifier">post</span><span class="special">(</span><span class="identifier">pool</span><span class="special">,</span> <span class="identifier">use_future</span><span class="special">([]{</span>
    <span class="comment">// ...</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">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
</pre></div><div class="section" title="5.&#160;Library vocabulary"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="executors.library_vocabulary"></a>5.&#160;Library vocabulary</h2></div></div></div><p>
      The central concept of this library is the <span class="emphasis"><em>executor</em></span> as
      a policy. An executor embodies a set of rules about where, when and how to
      run a submitted function object. For example:
    </p><div class="informaltable"><table class="table"><colgroup><col><col></colgroup><thead><tr><th>
              <p>
                Executor type
              </p>
            </th><th>
              <p>
                Executor rules
              </p>
            </th></tr></thead><tbody><tr><td>
              <p>
                <code class="computeroutput"><span class="identifier">system_executor</span></code>
              </p>
            </td><td>
              <p>
                Function objects are allowed to run on any thread in the process.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="computeroutput"><span class="identifier">thread_pool</span><span class="special">::</span><span class="identifier">executor_type</span></code>
              </p>
            </td><td>
              <p>
                Function objects are allowed to run on any thread in the pool, and
                nowhere else.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="computeroutput"><span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;</span></code>
              </p>
            </td><td>
              <p>
                Run function objects according to the underlying executor's rules,
                but also run them in FIFO order and not concurrently. Do not block
                the submitter if the FIFO queue is non-empty.
              </p>
            </td></tr></tbody></table></div><p>
      Executors are ultimately defined by a set of type requirements, so the set
      of executors isn't limited to those listed here. Like allocators, library users
      can develop custom executor types to implement their own rules. Executors allow
      us to encapsulate all sorts of additional information and behaviour on a fine-grained
      basis, such as:
    </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
          Priority.
        </li><li class="listitem">
          Preferred CPU affinity.
        </li><li class="listitem">
          Security credentials or impersonation context.
        </li><li class="listitem">
          How exceptions should be handled.
        </li></ul></div><p>
      Certain objects may have an <span class="emphasis"><em>associated executor</em></span>, which
      specifies how any function objects related to the object should be executed.
      For example, we may want to say that all event callbacks associated with a
      network protocol implementation should execute on a particular thread, or that
      a task should run at a particular priority. The notion of an associated executor
      allows us to decouple the specification of execution behaviour from the actual
      point of execution.
    </p><p>
      An <span class="emphasis"><em>execution context</em></span> is a place where function objects
      are executed. Where executors are lightweight and cheap to copy, an execution
      context is typically long-lived and non-copyable. It may contain additional
      state such as timer queues, socket reactors, or hidden threads to emulate asynchronous
      functionality. Examples of execution contexts include <code class="computeroutput"><span class="identifier">thread_pool</span></code>,
      <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>, a Boost.Asio
      <code class="computeroutput"><span class="identifier">io_service</span></code>, and the set of
      all threads in the process.
    </p><p>
      We say that a <code class="computeroutput"><span class="identifier">thread_pool</span></code>
      <span class="emphasis"><em>is</em></span> an execution context, and that it <span class="emphasis"><em>has</em></span>
      an executor. The thread pool contains long-lived state, namely the threads
      that persist until the pool is shut down. The thread pool's executor embodies
      the rule: <span class="emphasis"><em>run functions in the pool and nowhere else</em></span>.
      The thread pool's executor may be obtained by calling its <code class="computeroutput"><span class="identifier">get_executor</span><span class="special">()</span></code> member function.
    </p><p>
      To submit a function object to an executor or execution context, we can choose
      from one of three fundamental operations: <span class="emphasis"><em>dispatch</em></span>, <span class="emphasis"><em>post</em></span>
      and <span class="emphasis"><em>defer</em></span>. These operations differ in the eagerness with
      which they run the submitted function.
    </p><p>
      A dispatch operation is the most eager.
    </p><pre class="programlisting"><span class="identifier">dispatch</span><span class="special">(</span><span class="identifier">ex</span><span class="special">,</span> <span class="special">[]{</span> <span class="special">...</span> <span class="special">});</span>
</pre><p>
      It means: <span class="emphasis"><em>block the calling thread until the function completes,
      if the rules allow it; otherwise, submit for later execution</em></span>.
    </p><div class="informaltable"><table class="table"><colgroup><col><col><col></colgroup><thead><tr><th>
              <p>
                Executor type
              </p>
            </th><th>
              <p>
                Executor rules
              </p>
            </th><th>
              <p>
                Behaviour of dispatch
              </p>
            </th></tr></thead><tbody><tr><td>
              <p>
                <code class="computeroutput"><span class="identifier">system_executor</span></code>
              </p>
            </td><td>
              <p>
                Function objects are allowed to run on any thread in the process.
              </p>
            </td><td>
              <p>
                Always runs the function object before returning from <code class="computeroutput"><span class="identifier">dispatch</span><span class="special">()</span></code>.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="computeroutput"><span class="identifier">thread_pool</span><span class="special">::</span><span class="identifier">executor_type</span></code>
              </p>
            </td><td>
              <p>
                Function objects are allowed to run on any thread in the pool, and
                nowhere else.
              </p>
            </td><td>
              <p>
                If we are inside the thread pool, runs the function object before
                returning from <code class="computeroutput"><span class="identifier">dispatch</span><span class="special">()</span></code>. Otherwise, adds to the thread
                pool's work queue.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="computeroutput"><span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;</span></code>
              </p>
            </td><td>
              <p>
                Run function objects according to the underlying executor's rules,
                but also run them in FIFO order and not concurrently. Do not block
                the submitter if the FIFO queue is non-empty.
              </p>
            </td><td>
              <p>
                If we are inside the strand, or if the strand queue is empty, runs
                the function object before returning from <code class="computeroutput"><span class="identifier">dispatch</span><span class="special">()</span></code>. Otherwise, adds to the strand's
                work queue.
              </p>
            </td></tr></tbody></table></div><p>
      A consequence of calling <code class="computeroutput"><span class="identifier">dispatch</span><span class="special">()</span></code> is that, if the executor&#8217;s rules allow
      it, the compiler is able to inline the function object call.
    </p><p>
      A post operation, on the other hand, is not permitted to run the function object
      itself.
    </p><pre class="programlisting"><span class="identifier">post</span><span class="special">(</span><span class="identifier">ex</span><span class="special">,</span> <span class="special">[]{</span> <span class="special">...</span> <span class="special">});</span>
</pre><p>
      It means: <span class="emphasis"><em>submit the function for later execution; never block the
      calling thread to wait for the function to complete</em></span>. A posted function
      is scheduled for execution as soon as possible, according to the rules of the
      executor.
    </p><div class="informaltable"><table class="table"><colgroup><col><col><col></colgroup><thead><tr><th>
              <p>
                Executor type
              </p>
            </th><th>
              <p>
                Executor rules
              </p>
            </th><th>
              <p>
                Behaviour of post
              </p>
            </th></tr></thead><tbody><tr><td>
              <p>
                <code class="computeroutput"><span class="identifier">system_executor</span></code>
              </p>
            </td><td>
              <p>
                Function objects are allowed to run on any thread in the process.
              </p>
            </td><td>
              <p>
                Like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">async</span><span class="special">()</span></code>,
                the system executor may allocate <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span></code>
                objects to run the submitted function objects. A typical implementation
                may be to use a hidden system-wide thread pool.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="computeroutput"><span class="identifier">thread_pool</span><span class="special">::</span><span class="identifier">executor_type</span></code>
              </p>
            </td><td>
              <p>
                Function objects are allowed to run on any thread in the pool, and
                nowhere else.
              </p>
            </td><td>
              <p>
                Adds the function object to the thread pool's work queue.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="computeroutput"><span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;</span></code>
              </p>
            </td><td>
              <p>
                Run function objects according to the underlying executor's rules,
                but also run them in FIFO order and not concurrently. Do not block
                the submitter if the FIFO queue is non-empty.
              </p>
            </td><td>
              <p>
                Adds the function object to the strand's work queue.
              </p>
            </td></tr></tbody></table></div><p>
      Finally, the defer operation is the least eager of the three.
    </p><pre class="programlisting"><span class="identifier">defer</span><span class="special">(</span><span class="identifier">ex</span><span class="special">,</span> <span class="special">[]{</span> <span class="special">...</span> <span class="special">});</span>
</pre><p>
      A defer operation is similar to a post operation, in that it means: <span class="emphasis"><em>submit
      the function for later execution; never block the calling thread to wait for
      the function to complete.</em></span> However, a defer operation also <span class="emphasis"><em>implies
      a relationship between the caller and the function object being submitted</em></span>.
      It is intended for use when submitting a function object that represents a
      continuation of the caller.
    </p><div class="informaltable"><table class="table"><colgroup><col><col><col></colgroup><thead><tr><th>
              <p>
                Executor type
              </p>
            </th><th>
              <p>
                Executor rules
              </p>
            </th><th>
              <p>
                Behaviour of defer
              </p>
            </th></tr></thead><tbody><tr><td>
              <p>
                <code class="computeroutput"><span class="identifier">system_executor</span></code>
              </p>
            </td><td>
              <p>
                Function objects are allowed to run on any thread in the process.
              </p>
            </td><td>
              <p>
                If the caller is executing within the system-wide thread pool, saves
                the function object to a thread-local queue. Once control returns
                to the system thread pool, the function object is scheduled for execution
                as soon as possible.<br> <br> If the caller is not inside the
                system thread pool, behaves as a post operation.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="computeroutput"><span class="identifier">thread_pool</span><span class="special">::</span><span class="identifier">executor_type</span></code>
              </p>
            </td><td>
              <p>
                Function objects are allowed to run on any thread in the pool, and
                nowhere else.
              </p>
            </td><td>
              <p>
                If the caller is executing within the thread pool, saves the function
                object to a thread-local queue. Once control returns to the thread
                pool, the function object is scheduled for execution as soon as possible.<br>
                <br> If the caller is not inside the specified thread pool, behaves
                as a post operation.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="computeroutput"><span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;</span></code>
              </p>
            </td><td>
              <p>
                Run function objects according to the underlying executor's rules,
                but also run them in FIFO order and not concurrently. Do not block
                the submitter if the FIFO queue is non-empty.
              </p>
            </td><td>
              <p>
                Adds the function object to the strand's work queue.
              </p>
            </td></tr></tbody></table></div></div><div class="section" title="6.&#160;Library examples"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="executors.library_examples"></a>6.&#160;Library examples</h2></div></div></div><div class="toc"><dl><dt><span class="section"><a href="#executors.emulating___std__async___">6.1. Emulating <code class="literal">std::async()</code></a></span></dt><dt><span class="section"><a href="#executors.active_objects">6.2. Active objects</a></span></dt><dt><span class="section"><a href="#executors.activatable_objects">6.3. Activatable objects</a></span></dt><dt><span class="section"><a href="#executors.leader_followers_pattern">6.4. Leader/Followers pattern</a></span></dt><dt><span class="section"><a href="#executors.asynchronous_operations">6.5. Asynchronous operations</a></span></dt><dt><span class="section"><a href="#executors.pipelines">6.6. Pipelines</a></span></dt><dt><span class="section"><a href="#executors.actors">6.7. Actors</a></span></dt><dt><span class="section"><a href="#executors.priority_scheduler">6.8. Priority scheduler</a></span></dt></dl></div><p>
      In this section we will examine a selection of examples, to see how the proposed
      executors library supports a range of use cases.
    </p><div class="section" title="6.1.&#160;Emulating std::async()"><div class="titlepage"><div><div><h3 class="title"><a name="executors.emulating___std__async___"></a>6.1.&#160;Emulating <code class="literal">std::async()</code></h3></div></div></div><p>
        The behaviour of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">async</span><span class="special">()</span></code>
        function, when used with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">launch</span><span class="special">::</span><span class="identifier">async</span></code>,
        may be trivially emulated as follows:
      </p><pre class="programlisting"><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="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span>
<span class="keyword">auto</span> <span class="identifier">async</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="identifier">Args</span><span class="special">&amp;&amp;...</span> <span class="identifier">args</span><span class="special">)</span>
<span class="special">{</span>
  <span class="keyword">return</span> <span class="identifier">post</span><span class="special">(</span>
    <span class="identifier">use_future</span><span class="special">(</span>
      <span class="identifier">std</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">&gt;(</span><span class="identifier">f</span><span class="special">),</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Args</span><span class="special">&gt;(</span><span class="identifier">args</span><span class="special">)...)));</span>
<span class="special">}</span>
</pre><p>
        Starting from the inside out, the expression:
      </p><pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">&gt;(</span><span class="identifier">f</span><span class="special">),</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Args</span><span class="special">&gt;(</span><span class="identifier">args</span><span class="special">)...)</span>
</pre><p>
        creates a function object that will invoke <code class="computeroutput"><span class="identifier">f</span></code>
        with the specified arguments. Next:
      </p><pre class="programlisting"><span class="identifier">use_future</span><span class="special">(...)</span>
</pre><p>
        returns an object that will be lazily converted into a function object similar
        to<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span><span class="special">&lt;&gt;</span></code>.
        We could also have used <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span><span class="special">&lt;&gt;</span></code> directly, as in:
      </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="identifier">std</span><span class="special">::</span><span class="identifier">result_of_t</span><span class="special">&lt;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">decay_t</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">&gt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">decay_t</span><span class="special">&lt;</span><span class="identifier">Args</span><span class="special">&gt;...)&gt;&gt;(...)</span>
</pre><p>
        In this example, the <code class="computeroutput"><span class="identifier">use_future</span><span class="special">()</span></code> function saves on typing by determining
        the return type of <code class="computeroutput"><span class="identifier">F</span></code> for
        us. Finally:
      </p><pre class="programlisting"><span class="identifier">post</span><span class="special">(...)</span>
</pre><p>
        submits the function object for execution on another thread, and then returns
        immediately. When we submit the result of <code class="computeroutput"><span class="identifier">use_future</span><span class="special">()</span></code> (or if we were to submit a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span><span class="special">&lt;&gt;</span></code>), <code class="computeroutput"><span class="identifier">post</span><span class="special">()</span></code> automatically deduces its return type to
        be the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;&gt;</span></code>
        type produced by the task. This future object is then returned from our version
        of <code class="computeroutput"><span class="identifier">async</span><span class="special">()</span></code>.
        Note that, unlike <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">async</span><span class="special">()</span></code>,
        the returned future object's destructor will not block.
      </p><div class="sidebar"><p class="title"><b></b></p><p>
        See complete example at:<br> <a href="https://github.com/chriskohlhoff/executors/blob/v0.2-branch/src/examples/executor/async_1.cpp" target="_top">https://github.com/chriskohlhoff/executors/blob/v0.2-branch/src/examples/executor/async_1.cpp</a>
      </p></div></div><div class="section" title="6.2.&#160;Active objects"><div class="titlepage"><div><div><h3 class="title"><a name="executors.active_objects"></a>6.2.&#160;Active objects</h3></div></div></div><p>
        In the Active Object design pattern, all operations associated with an object
        are run in its own private thread.
      </p><p>
        To implement an active object, we begin by defining a class member that is
        a thread pool containing a single thread.
      </p><pre class="programlisting"><span class="keyword">class</span> <span class="identifier">bank_account</span>
<span class="special">{</span>
  <span class="keyword">int</span> <span class="identifier">balance_</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
  <span class="keyword">mutable</span> <span class="identifier">thread_pool</span> <span class="identifier">pool_</span><span class="special">{</span><span class="number">1</span><span class="special">};</span>
  <span class="comment">// ...</span>
<span class="special">};</span>
</pre><p>
        We then define each public member function so that it posts its implementation
        to the thread pool.
      </p><pre class="programlisting"><span class="keyword">class</span> <span class="identifier">bank_account</span>
<span class="special">{</span>
  <span class="comment">// ...</span>
  <span class="keyword">void</span> <span class="identifier">deposit</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">amount</span><span class="special">)</span>
  <span class="special">{</span>
    <span class="identifier">post</span><span class="special">(</span><span class="identifier">pool_</span><span class="special">,</span>
      <span class="identifier">use_future</span><span class="special">([=]</span>
        <span class="special">{</span>
          <span class="identifier">balance_</span> <span class="special">+=</span> <span class="identifier">amount</span><span class="special">;</span>
        <span class="special">})).</span><span class="identifier">get</span><span class="special">();</span>
  <span class="special">}</span>
  <span class="comment">// ...</span>
<span class="special">};</span>
</pre><p>
        In more detail, to implement an active object operation we begin by defining
        the body of the function:
      </p><pre class="programlisting"><span class="special">[=]</span>
<span class="special">{</span>
  <span class="identifier">balance_</span> <span class="special">+=</span> <span class="identifier">amount</span><span class="special">;</span>
<span class="special">}</span>
</pre><p>
        which we then wrap in a lazily created <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">packaged_task</span><span class="special">&lt;&gt;</span></code> equivalent:
      </p><pre class="programlisting"><span class="identifier">use_future</span><span class="special">(...)</span>
</pre><p>
        Finally, we submit the packaged task to the pool and wait for it to complete.
        When we submit the result of <code class="computeroutput"><span class="identifier">use_future</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">post</span><span class="special">()</span></code> automatically deduces its return type to
        be the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;&gt;</span></code>
        type produced by the task. We can use this future to block until the operation
        is complete.
      </p><pre class="programlisting"><span class="identifier">post</span><span class="special">(...).</span><span class="identifier">get</span><span class="special">();</span>
</pre><div class="sidebar"><p class="title"><b></b></p><p>
        See complete example at:<br> <a href="https://github.com/chriskohlhoff/executors/blob/v0.2-branch/src/examples/executor/bank_account_2.cpp" target="_top">https://github.com/chriskohlhoff/executors/blob/v0.2-branch/src/examples/executor/bank_account_2.cpp</a>
      </p></div></div><div class="section" title="6.3.&#160;Activatable objects"><div class="titlepage"><div><div><h3 class="title"><a name="executors.activatable_objects"></a>6.3.&#160;Activatable objects</h3></div></div></div><p>
        An Activatable object is a variant of the Active Object pattern where the
        object does not have a private thread of its own. Instead, it can borrow
        one of the calling threads to process operations<sup>[<a name="executors.library_examples.activatable_objects.f0" href="#ftn.executors.library_examples.activatable_objects.f0" class="footnote">1</a>]</sup>. However, like Active Object, it ensures that all member state
        changes do not occur on more than one thread at a time.
      </p><p>
        To implement an activatable object, we create a strand on the system executor.
      </p><pre class="programlisting"><span class="keyword">class</span> <span class="identifier">bank_account</span>
<span class="special">{</span>
  <span class="keyword">int</span> <span class="identifier">balance_</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
  <span class="keyword">mutable</span> <span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">system_executor</span><span class="special">&gt;</span> <span class="identifier">strand_</span><span class="special">;</span>
  <span class="comment">// ...</span>
<span class="special">};</span>
</pre><p>
        We then define each public member function so that it dispatches its implementation
        to the strand.
      </p><pre class="programlisting"><span class="keyword">class</span> <span class="identifier">bank_account</span>
<span class="special">{</span>
  <span class="comment">// ...</span>
  <span class="keyword">void</span> <span class="identifier">deposit</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">amount</span><span class="special">)</span>
  <span class="special">{</span>
    <span class="identifier">dispatch</span><span class="special">(</span><span class="identifier">strand_</span><span class="special">,</span>
      <span class="identifier">use_future</span><span class="special">([=]</span>
        <span class="special">{</span>
          <span class="identifier">balance_</span> <span class="special">+=</span> <span class="identifier">amount</span><span class="special">;</span>
        <span class="special">})).</span><span class="identifier">get</span><span class="special">();</span>
  <span class="special">}</span>
  <span class="comment">// ...</span>
<span class="special">};</span>
</pre><p>
        Recall that a <code class="computeroutput"><span class="identifier">system_executor</span></code>
        object embodies this rule:
      </p><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Function objects are allowed to run on any thread in the process.</em></span>
        </p></blockquote></div><p>
        while a strand embodies this rule:
      </p><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Run function objects according to the underlying executor's rules,
          but also run them in FIFO order and not concurrently. Do not block the
          submitter if the FIFO queue is non-empty.</em></span>
        </p></blockquote></div><p>
        Finally, the call to <code class="computeroutput"><span class="identifier">dispatch</span><span class="special">()</span></code> means:
      </p><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Block the calling thread until the function completes, if the
          rules allow it; otherwise, submit for later execution.</em></span>
        </p></blockquote></div><p>
        Thus, when we combine <code class="computeroutput"><span class="identifier">system_executor</span></code>,
        <code class="computeroutput"><span class="identifier">strand</span></code> and <code class="computeroutput"><span class="identifier">dispatch</span><span class="special">()</span></code>:
      </p><pre class="programlisting"><span class="identifier">dispatch</span><span class="special">(</span><span class="identifier">strand_</span><span class="special">,</span> <span class="special">[]{</span> <span class="special">...</span> <span class="special">});</span>
</pre><p>
        we are effectively saying: <span class="emphasis"><em>if the strand is not busy, run the function
        object immediately</em></span>. If there is no contention on the strand, latency
        is minimised. If there is contention, the strand still ensures that the function
        object never runs concurrently with any other function object submitted through
        the same strand.
      </p><div class="sidebar"><p class="title"><b></b></p><p>
        See complete example at:<br> <a href="https://github.com/chriskohlhoff/executors/blob/v0.2-branch/src/examples/executor/bank_account_3.cpp" target="_top">https://github.com/chriskohlhoff/executors/blob/v0.2-branch/src/examples/executor/bank_account_3.cpp</a>
      </p></div></div><div class="section" title="6.4.&#160;Leader/Followers pattern"><div class="titlepage"><div><div><h3 class="title"><a name="executors.leader_followers_pattern"></a>6.4.&#160;Leader/Followers pattern</h3></div></div></div><p>
        The Leader/Followers design pattern is a model where multiple threads take
        turns to wait on event sources in order to dispatch and process incoming
        events.
      </p><p>
        Consider an example where a connection handler is responsible for receiving
        messages from a client via UDP. The Leader/Followers pattern is implemented
        using a <code class="computeroutput"><span class="identifier">thread_pool</span></code> object:
      </p><pre class="programlisting"><span class="keyword">class</span> <span class="identifier">connection_handler</span>
<span class="special">{</span>
  <span class="comment">// ...</span>
<span class="keyword">private</span><span class="special">:</span>
  <span class="identifier">udp_socket</span> <span class="identifier">socket_</span><span class="special">;</span>
  <span class="identifier">thread_pool</span> <span class="identifier">thread_pool_</span><span class="special">;</span>
  <span class="comment">// ...</span>
<span class="special">};</span>
</pre><p>
        and involves the sequence of operations below.
      </p><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">connection_handler</span><span class="special">::</span><span class="identifier">receive_and_dispatch</span><span class="special">()</span>
<span class="special">{</span>
</pre><p>
        The leader thread waits for the next message to arrive.
      </p><pre class="programlisting">  <span class="keyword">char</span> <span class="identifier">buffer</span><span class="special">[</span><span class="number">1024</span><span class="special">];</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">length</span> <span class="special">=</span> <span class="identifier">socket_</span><span class="special">.</span><span class="identifier">receive</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">,</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">));</span>
</pre><p>
        A new message has arrived. The leader thread promotes a follower to become
        the new leader.
      </p><pre class="programlisting">  <span class="identifier">std</span><span class="special">::</span><span class="identifier">experimental</span><span class="special">::</span><span class="identifier">concurrency</span><span class="special">::</span><span class="identifier">post</span><span class="special">(</span><span class="identifier">thread_pool_</span><span class="special">,</span>
      <span class="special">[</span><span class="keyword">this</span><span class="special">]{</span> <span class="identifier">receive_and_dispatch</span><span class="special">();</span> <span class="special">});</span>
</pre><p>
        The now former leader processes the message.
      </p><pre class="programlisting">  <span class="comment">// Process the new message and pass it to the order management bus.</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">istringstream</span> <span class="identifier">is</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">,</span> <span class="identifier">length</span><span class="special">));</span>
  <span class="identifier">order_management</span><span class="special">::</span><span class="identifier">new_order</span> <span class="identifier">event</span><span class="special">;</span>
  <span class="keyword">if</span> <span class="special">(</span><span class="identifier">is</span> <span class="special">&gt;&gt;</span> <span class="identifier">event</span><span class="special">)</span>
    <span class="identifier">order_management_bus_</span><span class="special">.</span><span class="identifier">dispatch_event</span><span class="special">(</span><span class="identifier">event</span><span class="special">);</span>
<span class="special">}</span>
</pre><p>
        When the function returns, the former leader automatically returns to the
        pool as a follower thread.
      </p><div class="sidebar"><p class="title"><b></b></p><p>
        See complete example at:<br> <a href="https://github.com/chriskohlhoff/executors/blob/v0.2-branch/src/examples/trading/server/" target="_top">https://github.com/chriskohlhoff/executors/blob/v0.2-branch/src/examples/trading/server/</a>
      </p></div></div><div class="section" title="6.5.&#160;Asynchronous operations"><div class="titlepage"><div><div><h3 class="title"><a name="executors.asynchronous_operations"></a>6.5.&#160;Asynchronous operations</h3></div></div></div><p>
        Asynchronous operations are often chained, and in many cases an object may
        be associated with two or more chains. For example, an object to manage a
        connection may contain one chain to do the writing, and another to do the
        reading:
      </p><pre class="programlisting"><span class="keyword">class</span> <span class="identifier">connection</span>
<span class="special">{</span>
  <span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket_</span><span class="special">;</span>
  <span class="identifier">mutable_buffers_1</span> <span class="identifier">in_buffer_</span><span class="special">;</span>
  <span class="identifier">mutable_buffers_1</span> <span class="identifier">out_buffer_</span><span class="special">;</span>

  <span class="comment">// ...</span>

  <span class="keyword">void</span> <span class="identifier">do_read</span><span class="special">()</span>
  <span class="special">{</span>
    <span class="identifier">socket_</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">in_buffer_</span><span class="special">,</span>
      <span class="special">[</span><span class="keyword">this</span><span class="special">](</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">n</span><span class="special">)</span>
      <span class="special">{</span>
        <span class="comment">// ... process input data ...</span>
        <span class="keyword">if</span> <span class="special">(!</span><span class="identifier">ec</span><span class="special">)</span> <span class="identifier">do_read</span><span class="special">();</span>
      <span class="special">});</span>
  <span class="special">}</span>

  <span class="keyword">void</span> <span class="identifier">do_write</span><span class="special">()</span>
  <span class="special">{</span>
    <span class="comment">// ... generate output data ...</span>
    <span class="identifier">async_write</span><span class="special">(</span><span class="identifier">socket_</span><span class="special">,</span> <span class="identifier">out_buffer_</span><span class="special">,</span>
      <span class="special">[</span><span class="keyword">this</span><span class="special">](</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">n</span><span class="special">)</span>
      <span class="special">{</span>
        <span class="keyword">if</span> <span class="special">(!</span><span class="identifier">ec</span><span class="special">)</span> <span class="identifier">do_write</span><span class="special">();</span>
      <span class="special">});</span>
  <span class="special">}</span>
<span class="special">};</span>
</pre><p>
        When these chains are run on a single-threaded event loop, it is not possible
        for more than one completion handler to run at any given time. This means
        that no synchronisation is required to protected shared data. However, if
        handlers are executed on a thread pool then some form of synchronisation
        will be required to avoid introducing data races.
      </p><p>
        The proposed library provides the <code class="computeroutput"><span class="identifier">strand</span><span class="special">&lt;&gt;</span></code> template to synchronise handlers.
        A strand ensures that completion handlers never run concurrently, and explicit
        synchronisation (such as a mutex) is still not required to protect shared
        data. To implement this, we use the one strand for all asynchronous operations
        associated with the object.
      </p><pre class="programlisting"><span class="keyword">class</span> <span class="identifier">connection</span>
<span class="special">{</span>
  <span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">socket_</span><span class="special">;</span>
  <span class="identifier">mutable_buffers_1</span> <span class="identifier">in_buffer_</span><span class="special">;</span>
  <span class="identifier">mutable_buffers_1</span> <span class="identifier">out_buffer_</span><span class="special">;</span>
  <span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">io_service</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&gt;</span> <span class="identifier">strand_</span><span class="special">;</span>

  <span class="comment">// ...</span>

  <span class="keyword">void</span> <span class="identifier">do_read</span><span class="special">()</span>
  <span class="special">{</span>
    <span class="identifier">socket_</span><span class="special">.</span><span class="identifier">async_read_some</span><span class="special">(</span><span class="identifier">in_buffer_</span><span class="special">,</span>
      <span class="identifier">bind_executor</span><span class="special">(</span><span class="identifier">strand_</span><span class="special">,</span> <span class="special">[</span><span class="keyword">this</span><span class="special">](</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">n</span><span class="special">)</span>
        <span class="special">{</span>
          <span class="comment">// ... process input data ...</span>
          <span class="keyword">if</span> <span class="special">(!</span><span class="identifier">ec</span><span class="special">)</span> <span class="identifier">do_read</span><span class="special">();</span>
        <span class="special">}));</span>
  <span class="special">}</span>

  <span class="keyword">void</span> <span class="identifier">do_write</span><span class="special">()</span>
  <span class="special">{</span>
    <span class="comment">// ... generate output data ...</span>
    <span class="identifier">async_write</span><span class="special">(</span><span class="identifier">socket_</span><span class="special">,</span> <span class="identifier">out_buffer_</span><span class="special">,</span>
      <span class="identifier">bind_executor</span><span class="special">(</span><span class="identifier">strand_</span><span class="special">,</span> <span class="special">[</span><span class="keyword">this</span><span class="special">](</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">n</span><span class="special">)</span>
        <span class="special">{</span>
          <span class="keyword">if</span> <span class="special">(!</span><span class="identifier">ec</span><span class="special">)</span> <span class="identifier">do_write</span><span class="special">();</span>
        <span class="special">}));</span>
  <span class="special">}</span>
<span class="special">};</span>
</pre><p>
        The <code class="computeroutput"><span class="identifier">bind_executor</span></code> function
        is used to associate an executor with an object. In this example, we used
        <code class="computeroutput"><span class="identifier">bind_executor</span></code> to associate
        the strand with each of the lambdas. The <code class="computeroutput"><span class="identifier">bind_executor</span></code>
        function works with any executor or execution context. For example, here
        we associate a thread pool with a lamdba:
      </p><pre class="programlisting"><span class="identifier">async_getline</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cin</span><span class="special">,</span>
    <span class="identifier">bind_executor</span><span class="special">(</span><span class="identifier">pool</span><span class="special">,</span> <span class="special">[](</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">line</span><span class="special">)</span>
      <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Line: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">line</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
      <span class="special">}));</span>
</pre><p>
        Rather than using the <code class="computeroutput"><span class="identifier">bind_executor</span></code>
        function, the associated executor may be manually specified by providing
        a nested <code class="computeroutput"><span class="identifier">executor_type</span></code> typedef
        and <code class="computeroutput"><span class="identifier">get_executor</span><span class="special">()</span></code>
        member function.
      </p><pre class="programlisting"><span class="keyword">class</span> <span class="identifier">line_printer</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
  <span class="keyword">typedef</span> <span class="identifier">loop_scheduler</span><span class="special">::</span><span class="identifier">executor_type</span> <span class="identifier">executor_type</span><span class="special">;</span>

  <span class="keyword">explicit</span> <span class="identifier">line_printer</span><span class="special">(</span><span class="identifier">loop_scheduler</span><span class="special">&amp;</span> <span class="identifier">s</span><span class="special">)</span>
    <span class="special">:</span> <span class="identifier">executor_</span><span class="special">(</span><span class="identifier">s</span><span class="special">.</span><span class="identifier">get_executor</span><span class="special">())</span>
  <span class="special">{</span>
  <span class="special">}</span>

  <span class="identifier">executor_type</span> <span class="identifier">get_executor</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span>
  <span class="special">{</span>
    <span class="keyword">return</span> <span class="identifier">executor_</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="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">line</span><span class="special">)</span>
  <span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Line: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">line</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
  <span class="special">}</span>

<span class="keyword">private</span><span class="special">:</span>
  <span class="identifier">loop_scheduler</span><span class="special">::</span><span class="identifier">executor_type</span> <span class="identifier">executor_</span><span class="special">;</span>
<span class="special">};</span>

<span class="comment">// ...</span>

<span class="identifier">async_getline</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cin</span><span class="special">,</span> <span class="identifier">line_printer</span><span class="special">(</span><span class="identifier">scheduler</span><span class="special">));</span>
</pre><p>
        For this to work correctly, the <code class="computeroutput"><span class="identifier">async_getline</span></code>
        asynchronous operation must participate in an executor-aware model. To be
        executor-aware, an asynchronous operation must:
      </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
            Ask the completion handler for its associated executor, by calling <code class="computeroutput"><span class="identifier">get_associated_executor</span></code>.
          </li><li class="listitem">
            While pending, maintain an <code class="computeroutput"><span class="identifier">executor_work_guard</span></code>
            object for the associated executor. This tells the executor to expect
            a function object to be submitted in the future. A thread pool, for example,
            will know that it still has work to do and needs to keep running.
          </li><li class="listitem">
            Dispatch, post or defer any intermediate handlers, and the final completion
            handler, through the associated executor. This ensures that all handlers
            are executed according to the executors rules.
          </li></ul></div><p>
        Our <code class="computeroutput"><span class="identifier">async_getline</span></code> operation
        can then be written as follows:
      </p><pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Handler</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">async_getline</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span><span class="special">&amp;</span> <span class="identifier">is</span><span class="special">,</span> <span class="identifier">Handler</span> <span class="identifier">handler</span><span class="special">)</span>
<span class="special">{</span>
</pre><p>
        The <code class="computeroutput"><span class="identifier">make_work_guard</span></code> function
        automatically obtains the associated executor and creates an <code class="computeroutput"><span class="identifier">executor_work_guard</span></code> object for it.
      </p><pre class="programlisting">  <span class="keyword">auto</span> <span class="identifier">work</span> <span class="special">=</span> <span class="identifier">make_work_guard</span><span class="special">(</span><span class="identifier">handler</span><span class="special">);</span>
</pre><p>
        The asynchronous operation itself is posted outside of the associated executor.
        This is because we want the line reading to be performed asynchronously with
        respect to the caller.
      </p><pre class="programlisting">  <span class="identifier">post</span><span class="special">([&amp;</span><span class="identifier">is</span><span class="special">,</span> <span class="identifier">work</span><span class="special">,</span> <span class="identifier">handler</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">handler</span><span class="special">)]()</span> <span class="keyword">mutable</span>
      <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">line</span><span class="special">;</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">getline</span><span class="special">(</span><span class="identifier">is</span><span class="special">,</span> <span class="identifier">line</span><span class="special">);</span>
</pre><p>
        Once the asynchronous work is complete, we execute the completion handler
        via its associated executor.
      </p><pre class="programlisting">        <span class="comment">// Pass the result to the handler, via the associated executor.</span>
        <span class="identifier">dispatch</span><span class="special">(</span><span class="identifier">work</span><span class="special">.</span><span class="identifier">get_executor</span><span class="special">(),</span>
            <span class="special">[</span><span class="identifier">line</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">line</span><span class="special">),</span> <span class="identifier">handler</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">handler</span><span class="special">)]()</span> <span class="keyword">mutable</span>
            <span class="special">{</span>
              <span class="identifier">handler</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">line</span><span class="special">));</span>
            <span class="special">});</span>
      <span class="special">});</span>
<span class="special">}</span>
</pre><div class="sidebar"><p class="title"><b></b></p><p>
        See complete example at:<br> <a href="https://github.com/chriskohlhoff/executors/blob/v0.2-branch/src/examples/executor/async_op_1.cpp" target="_top">https://github.com/chriskohlhoff/executors/blob/v0.2-branch/src/examples/executor/async_op_1.cpp</a>
      </p></div><p>
        When composing asynchronous operations, intermediate operations can simply
        reuse the associated executor of the final handler.
      </p><pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Handler</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">async_getlines</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span><span class="special">&amp;</span> <span class="identifier">is</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">init</span><span class="special">,</span> <span class="identifier">Handler</span> <span class="identifier">handler</span><span class="special">)</span>
<span class="special">{</span>
  <span class="comment">// Get the final handler's associated executor.</span>
  <span class="keyword">auto</span> <span class="identifier">ex</span> <span class="special">=</span> <span class="identifier">get_associated_executor</span><span class="special">(</span><span class="identifier">handler</span><span class="special">);</span>

  <span class="comment">// Use the associated executor for each operation in the composition.</span>
  <span class="identifier">async_getline</span><span class="special">(</span><span class="identifier">is</span><span class="special">,</span>
      <span class="identifier">bind_executor</span><span class="special">(</span><span class="identifier">ex</span><span class="special">,</span> <span class="special">[&amp;</span><span class="identifier">is</span><span class="special">,</span> <span class="identifier">lines</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">init</span><span class="special">),</span> <span class="identifier">handler</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">handler</span><span class="special">)]</span>
        <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">line</span><span class="special">)</span> <span class="keyword">mutable</span>
        <span class="special">{</span>
          <span class="keyword">if</span> <span class="special">(</span><span class="identifier">line</span><span class="special">.</span><span class="identifier">empty</span><span class="special">())</span>
            <span class="identifier">handler</span><span class="special">(</span><span class="identifier">lines</span><span class="special">);</span>
          <span class="keyword">else</span>
            <span class="identifier">async_getlines</span><span class="special">(</span><span class="identifier">is</span><span class="special">,</span> <span class="identifier">lines</span> <span class="special">+</span> <span class="identifier">line</span> <span class="special">+</span> <span class="string">"\n"</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">handler</span><span class="special">));</span>
        <span class="special">}));</span>
<span class="special">}</span>
</pre><p>
        This ensures that all intermediate completion handlers are correctly executed
        according to the caller's executor's rules.
      </p><div class="sidebar"><p class="title"><b></b></p><p>
        See complete example at:<br> <a href="https://github.com/chriskohlhoff/executors/blob/v0.2-branch/src/examples/executor/async_op_2.cpp" target="_top">https://github.com/chriskohlhoff/executors/blob/v0.2-branch/src/examples/executor/async_op_2.cpp</a>
      </p></div></div><div class="section" title="6.6.&#160;Pipelines"><div class="titlepage"><div><div><h3 class="title"><a name="executors.pipelines"></a>6.6.&#160;Pipelines</h3></div></div></div><p>
        A pipeline is a sequence of two or more long-running functions, known as
        stages, with each stage passing data to the next via a queue. The initial
        stage acts as a source of data, the intermediate stages act as filters, and
        the final stage as a sink.
      </p><p>
        As an example, let us consider a small framework for implementing pipelines.
        The function used to construct a pipeline is declared as:
      </p><pre class="programlisting"><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="special">...</span> <span class="identifier">Tail</span><span class="special">&gt;</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="identifier">pipeline</span><span class="special">(</span><span class="identifier">F</span> <span class="identifier">f</span><span class="special">,</span> <span class="identifier">Tail</span><span class="special">...</span> <span class="identifier">t</span><span class="special">);</span>
</pre><p>
        This function returns a <code class="computeroutput"><span class="identifier">future</span></code>
        that can be used to wait until the pipeline is complete. The initial stage
        of the pipeline must be a function with signature:
      </p><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">initial</span><span class="special">(</span><span class="identifier">queue_front</span><span class="special">&lt;</span><span class="identifier">T</span><sub><span class="emphasis"><em>0</em></span></sub><span class="special">&gt;</span> <span class="identifier">out</span><span class="special">);</span>
</pre><p>
        The intermediate stages have signature:
      </p><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">intermediate</span><span class="special">(</span><span class="identifier">queue_back</span><span class="special">&lt;</span><span class="identifier">T</span><sub><span class="emphasis"><em>n</em></span></sub><span class="special">&gt;</span> <span class="identifier">in</span><span class="special">,</span> <span class="identifier">queue_front</span><span class="special">&lt;</span><span class="identifier">T</span><sub><span class="emphasis"><em>n+1</em></span></sub><span class="special">&gt;</span> <span class="identifier">out</span><span class="special">);</span>
</pre><p>
        The pipeline's final stage has the signature:
      </p><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">final</span><span class="special">(</span><span class="identifier">queue_back</span><span class="special">&lt;</span><span class="identifier">T</span><sub><span class="emphasis"><em>N</em></span></sub><span class="special">&gt;</span> <span class="identifier">in</span><span class="special">);</span>
</pre><p>
        By default, we want each stage of a pipeline to have its own thread. The
        pipeline framework achieves this by calling <code class="computeroutput"><span class="identifier">get_associated_executor</span></code>
        with two arguments:
      </p><pre class="programlisting"><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="special">...</span> <span class="identifier">Tail</span><span class="special">&gt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="identifier">pipeline</span><span class="special">(</span><span class="identifier">F</span> <span class="identifier">f</span><span class="special">,</span> <span class="identifier">Tail</span><span class="special">...</span> <span class="identifier">t</span><span class="special">)</span>
<span class="special">{</span>
  <span class="comment">// ...</span>
  <span class="keyword">auto</span> <span class="identifier">ex</span> <span class="special">=</span> <span class="identifier">get_associated_executor</span><span class="special">(</span><span class="identifier">f</span><span class="special">,</span> <span class="identifier">thread_executor</span><span class="special">());</span>
  <span class="comment">// ...</span>
<span class="special">}</span>
</pre><p>
        The <code class="computeroutput"><span class="identifier">thread_executor</span></code> class
        is a custom executor type defined for the example. It starts a new thread
        for every function passed to <code class="computeroutput"><span class="identifier">dispatch</span></code>,
        <code class="computeroutput"><span class="identifier">post</span></code> or <code class="computeroutput"><span class="identifier">defer</span></code>.
        If the function object type <code class="computeroutput"><span class="identifier">F</span></code>
        already has an associated executor then that executor will be used. The
        <code class="computeroutput"><span class="identifier">thread_executor</span></code> is used for
        types that do not specify an associated executor.
      </p><p>
        So, when we construct and run a pipeline like this:
      </p><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">reader</span><span class="special">(</span><span class="identifier">queue_front</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">out</span><span class="special">);</span>
<span class="keyword">void</span> <span class="identifier">filter</span><span class="special">(</span><span class="identifier">queue_back</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">in</span><span class="special">,</span> <span class="identifier">queue_front</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">out</span><span class="special">);</span>
<span class="keyword">void</span> <span class="identifier">upper</span><span class="special">(</span><span class="identifier">queue_back</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">in</span><span class="special">,</span> <span class="identifier">queue_front</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">out</span><span class="special">);</span>
<span class="keyword">void</span> <span class="identifier">writer</span><span class="special">(</span><span class="identifier">queue_back</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">in</span><span class="special">);</span>

<span class="comment">// ...</span>

<span class="identifier">thread_pool</span> <span class="identifier">pool</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">f</span> <span class="special">=</span> <span class="identifier">pipeline</span><span class="special">(</span><span class="identifier">reader</span><span class="special">,</span> <span class="identifier">filter</span><span class="special">,</span> <span class="identifier">bind_executor</span><span class="special">(</span><span class="identifier">pool</span><span class="special">,</span> <span class="identifier">upper</span><span class="special">),</span> <span class="identifier">writer</span><span class="special">);</span>
<span class="identifier">f</span><span class="special">.</span><span class="identifier">wait</span><span class="special">();</span>
</pre><p>
        we are specifying that the the <code class="computeroutput"><span class="identifier">upper</span></code>
        stage should run on the thread pool, while <code class="computeroutput"><span class="identifier">reader</span></code>,
        <code class="computeroutput"><span class="identifier">filter</span></code> and <code class="computeroutput"><span class="identifier">writer</span></code> should use the default behaviour
        of launching a new thread.
      </p><div class="sidebar"><p class="title"><b></b></p><p>
        See complete example at:<br> <a href="https://github.com/chriskohlhoff/executors/blob/v0.2-branch/src/examples/executor/pipeline.cpp" target="_top">https://github.com/chriskohlhoff/executors/blob/v0.2-branch/src/examples/executor/pipeline.cpp</a>
      </p></div></div><div class="section" title="6.7.&#160;Actors"><div class="titlepage"><div><div><h3 class="title"><a name="executors.actors"></a>6.7.&#160;Actors</h3></div></div></div><p>
        The Actor model is a model for concurrency where objects, known as actors,
        communicate only by sending and receiving messages. Each actor's state is
        accessed only by its own internal thread or strand. This means that actors
        are inherently thread-safe.
      </p><p>
        To illustrate how executors may be used to facilitate actors, a tiny actor
        framework is included with the executors reference implementation. This framework
        is loosely based on the Theron library<sup>[<a name="executors.library_examples.actors.f0" href="#ftn.executors.library_examples.actors.f0" class="footnote">2</a>]</sup>.
      </p><p>
        To implement an actor using this framework, we start by deriving a class
        from <code class="computeroutput"><span class="identifier">actor</span></code>:
      </p><pre class="programlisting"><span class="keyword">class</span> <span class="identifier">member</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">actor</span>
<span class="special">{</span>
  <span class="comment">// ...</span>
</pre><p>
        When constructing an actor, we specify the executor to be used:
      </p><pre class="programlisting">  <span class="keyword">explicit</span> <span class="identifier">member</span><span class="special">(</span><span class="identifier">executor</span> <span class="identifier">e</span><span class="special">)</span>
    <span class="special">:</span> <span class="identifier">actor</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">e</span><span class="special">))</span>
  <span class="special">{</span>
    <span class="comment">// ...</span>
  <span class="special">}</span>
</pre><p>
        The polymorphic type <code class="computeroutput"><span class="identifier">executor</span></code>
        is used to allow the selection of an actor's executor to be delayed until
        runtime. All of an actor's message handlers are executed according to that
        policy. This could be a thread pool executor, but we may equally construct
        actors with an executor that <a class="link" href="#executors.priority_scheduler" title="6.8.&#160;Priority scheduler">knows
        about priorities</a>.
      </p><p>
        The actor's message handlers are member functions, identified by argument
        type, and may be arbitrarily registered or deregistered:
      </p><pre class="programlisting">  <span class="keyword">void</span> <span class="identifier">init_handler</span><span class="special">(</span><span class="identifier">actor_address</span> <span class="identifier">next</span><span class="special">,</span> <span class="identifier">actor_address</span> <span class="identifier">from</span><span class="special">)</span>
  <span class="special">{</span>
    <span class="comment">// ...</span>
    <span class="identifier">register_handler</span><span class="special">(&amp;</span><span class="identifier">member</span><span class="special">::</span><span class="identifier">token_handler</span><span class="special">);</span>
    <span class="identifier">deregister_handler</span><span class="special">(&amp;</span><span class="identifier">member</span><span class="special">::</span><span class="identifier">init_handler</span><span class="special">);</span>
  <span class="special">}</span>
</pre><p>
        Internally, the actor framework uses a per-actor <code class="computeroutput"><span class="identifier">strand</span></code>
        to ensure that the member functions are never called concurrently.
      </p><p>
        To send a message between actors we use either <code class="computeroutput"><span class="identifier">actor</span><span class="special">::</span><span class="identifier">send</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">actor</span><span class="special">::</span><span class="identifier">tail_send</span><span class="special">()</span></code>. The <code class="computeroutput"><span class="identifier">send</span><span class="special">()</span></code> operation is implemented in terms of the
        actor's executor's <code class="computeroutput"><span class="identifier">post</span><span class="special">()</span></code>
        member function. The <code class="computeroutput"><span class="identifier">tail_send</span><span class="special">()</span></code> function is a distinct operation and conveys
        additional information about the caller's intent which may be used to optimise
        inter-actor messaging. It is implemented in terms of <code class="computeroutput"><span class="identifier">defer</span><span class="special">()</span></code>.
      </p><pre class="programlisting">  <span class="keyword">void</span> <span class="identifier">token_handler</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">token</span><span class="special">,</span> <span class="identifier">actor_address</span> <span class="comment">/*from*/</span><span class="special">)</span>
  <span class="special">{</span>
    <span class="comment">// ...</span>
    <span class="identifier">tail_send</span><span class="special">(</span><span class="identifier">msg</span><span class="special">,</span> <span class="identifier">to</span><span class="special">);</span>
  <span class="special">}</span>

  <span class="comment">// ...</span>
<span class="special">};</span>
</pre><div class="sidebar"><p class="title"><b></b></p><p>
        See complete example at:<br> <a href="https://github.com/chriskohlhoff/executors/blob/v0.2-branch/src/examples/executor/actor.cpp" target="_top">https://github.com/chriskohlhoff/executors/blob/v0.2-branch/src/examples/executor/actor.cpp</a>
      </p></div></div><div class="section" title="6.8.&#160;Priority scheduler"><div class="titlepage"><div><div><h3 class="title"><a name="executors.priority_scheduler"></a>6.8.&#160;Priority scheduler</h3></div></div></div><p>
        Executor objects are lightweight and copyable to allow us to encapsulate
        all sorts of additional information and behaviour on a fine-grained basis.
        One use case for this is attaching priorities to function objects or tasks.
      </p><p>
        We begin by defining our priority scheduler class as an execution context.
        Internally, this class uses a priority queue to store pending function objects.
      </p><pre class="programlisting"><span class="keyword">class</span> <span class="identifier">priority_scheduler</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">execution_context</span>
<span class="special">{</span>
  <span class="comment">// ...</span>

<span class="keyword">private</span><span class="special">:</span>

  <span class="comment">// ...</span>

  <span class="keyword">struct</span> <span class="identifier">item_comp</span>
  <span class="special">{</span>
    <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">()(</span>
        <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span><span class="identifier">item_base</span><span class="special">&gt;&amp;</span> <span class="identifier">a</span><span class="special">,</span>
        <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span><span class="identifier">item_base</span><span class="special">&gt;&amp;</span> <span class="identifier">b</span><span class="special">)</span>
    <span class="special">{</span>
      <span class="keyword">return</span> <span class="identifier">a</span><span class="special">-&gt;</span><span class="identifier">priority_</span> <span class="special">&lt;</span> <span class="identifier">b</span><span class="special">-&gt;</span><span class="identifier">priority_</span><span class="special">;</span>
    <span class="special">}</span>
  <span class="special">};</span>

  <span class="identifier">std</span><span class="special">::</span><span class="identifier">mutex</span> <span class="identifier">mutex_</span><span class="special">;</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">condition_variable</span> <span class="identifier">condition_</span><span class="special">;</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">priority_queue</span><span class="special">&lt;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span><span class="identifier">item_base</span><span class="special">&gt;,</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span><span class="identifier">item_base</span><span class="special">&gt;&gt;,</span>
    <span class="identifier">item_comp</span><span class="special">&gt;</span> <span class="identifier">queue_</span><span class="special">;</span>
  <span class="keyword">bool</span> <span class="identifier">stopped_</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
<span class="special">};</span>
</pre><p>
        The <code class="computeroutput"><span class="identifier">priority_scheduler</span></code> class
        provides a nested class <code class="computeroutput"><span class="identifier">executor_type</span></code>
        which satisfies the executor type requirements, and a member function <code class="computeroutput"><span class="identifier">get_executor</span><span class="special">()</span></code>
        to obtain an executor object. On construction, an <code class="computeroutput"><span class="identifier">executor_type</span></code>
        object captures a reference to the priority scheduler, as well as the specified
        priority value.
      </p><pre class="programlisting"><span class="keyword">class</span> <span class="identifier">priority_scheduler</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">execution_context</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
  <span class="keyword">class</span> <span class="identifier">executor_type</span>
  <span class="special">{</span>
  <span class="keyword">public</span><span class="special">:</span>
    <span class="identifier">executor_type</span><span class="special">(</span><span class="identifier">priority_scheduler</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">pri</span><span class="special">)</span> <span class="keyword">noexcept</span>
      <span class="special">:</span> <span class="identifier">context_</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">),</span> <span class="identifier">priority_</span><span class="special">(</span><span class="identifier">pri</span><span class="special">)</span>
    <span class="special">{</span>
    <span class="special">}</span>

    <span class="comment">// ...</span>

  <span class="keyword">private</span><span class="special">:</span>
    <span class="identifier">priority_scheduler</span><span class="special">&amp;</span> <span class="identifier">context_</span><span class="special">;</span>
    <span class="keyword">int</span> <span class="identifier">priority_</span><span class="special">;</span>
  <span class="special">};</span>

  <span class="identifier">executor_type</span> <span class="identifier">get_executor</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">pri</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">noexcept</span>
  <span class="special">{</span>
    <span class="keyword">return</span> <span class="identifier">executor_type</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">pri</span><span class="special">);</span>
  <span class="special">}</span>

  <span class="comment">// ...</span>
<span class="special">};</span>
</pre><p>
        When a function object is submitted, the executor uses its stored priority
        to insert the function into the correct position in the priority queue:
      </p><pre class="programlisting"><span class="keyword">class</span> <span class="identifier">priority_scheduler</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">execution_context</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
  <span class="keyword">class</span> <span class="identifier">executor_type</span>
  <span class="special">{</span>
  <span class="keyword">public</span><span class="special">:</span>

    <span class="comment">// ...</span>

    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
    <span class="keyword">void</span> <span class="identifier">post</span><span class="special">(</span><span class="identifier">Func</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Alloc</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">)</span>
    <span class="special">{</span>
      <span class="keyword">auto</span> <span class="identifier">p</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocate_shared</span><span class="special">&lt;</span><span class="identifier">item</span><span class="special">&lt;</span><span class="identifier">Func</span><span class="special">&gt;&gt;(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">priority_</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">lock_guard</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">mutex</span><span class="special">&gt;</span> <span class="identifier">lock</span><span class="special">(</span><span class="identifier">context_</span><span class="special">.</span><span class="identifier">mutex_</span><span class="special">);</span>
      <span class="identifier">context_</span><span class="special">.</span><span class="identifier">queue_</span><span class="special">.</span><span class="identifier">push</span><span class="special">(</span><span class="identifier">p</span><span class="special">);</span>
      <span class="identifier">context_</span><span class="special">.</span><span class="identifier">condition_</span><span class="special">.</span><span class="identifier">notify_one</span><span class="special">();</span>
    <span class="special">}</span>

    <span class="comment">// ...</span>
  <span class="special">};</span>

  <span class="comment">// ...</span>
<span class="special">};</span>
</pre><p>
        The priority scheduler's executors can then be used like any other:
      </p><pre class="programlisting"><span class="identifier">priority_scheduler</span> <span class="identifier">sched</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">low</span> <span class="special">=</span> <span class="identifier">sched</span><span class="special">.</span><span class="identifier">get_executor</span><span class="special">(</span><span class="number">0</span><span class="special">);</span>
<span class="keyword">auto</span> <span class="identifier">med</span> <span class="special">=</span> <span class="identifier">sched</span><span class="special">.</span><span class="identifier">get_executor</span><span class="special">(</span><span class="number">1</span><span class="special">);</span>
<span class="keyword">auto</span> <span class="identifier">high</span> <span class="special">=</span> <span class="identifier">sched</span><span class="special">.</span><span class="identifier">get_executor</span><span class="special">(</span><span class="number">2</span><span class="special">);</span>
<span class="comment">// ...</span>
<span class="identifier">dispatch</span><span class="special">(</span><span class="identifier">low</span><span class="special">,</span> <span class="special">[]{</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"1\n"</span><span class="special">;</span> <span class="special">});</span>
<span class="identifier">dispatch</span><span class="special">(</span><span class="identifier">med</span><span class="special">,</span> <span class="special">[]{</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"2\n"</span><span class="special">;</span> <span class="special">});</span>
<span class="identifier">dispatch</span><span class="special">(</span><span class="identifier">high</span><span class="special">,</span> <span class="special">[]{</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"3\n"</span><span class="special">;</span> <span class="special">});</span>
</pre><div class="sidebar"><p class="title"><b></b></p><p>
        See complete example at:<br> <a href="https://github.com/chriskohlhoff/executors/blob/v0.2-branch/src/examples/executor/priority_scheduler.cpp" target="_top">https://github.com/chriskohlhoff/executors/blob/v0.2-branch/src/examples/executor/priority_scheduler.cpp</a>
      </p></div></div></div><div class="section" title="7.&#160;Summary of library facilities"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="executors.summary_of_library_facilities"></a>7.&#160;Summary of library facilities</h2></div></div></div><div class="informaltable"><table class="table"><colgroup><col><col><col></colgroup><thead><tr><th>
              <p>
                Header
              </p>
            </th><th>
              <p>
                Name
              </p>
            </th><th>
              <p>
                Description
              </p>
            </th></tr></thead><tbody><tr><td>
              <p>
                <code class="literal">executor</code>
              </p>
            </td><td>
              <p>
                Class template <code class="literal">async_result</code>
              </p>
            </td><td>
              <p>
                Determines the result of an asynchronous operation&#8217;s initiating
                function.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="literal">executor</code>
              </p>
            </td><td>
              <p>
                Class template <code class="literal">async_completion</code>
              </p>
            </td><td>
              <p>
                Helper to simplify implementation of an asynchronous operation.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="literal">executor</code>
              </p>
            </td><td>
              <p>
                Class template <code class="literal">associated_allocator</code>
              </p>
            </td><td>
              <p>
                Used to determine a handler&#8217;s associated allocator.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="literal">executor</code>
              </p>
            </td><td>
              <p>
                Function <code class="literal">get_associated_allocator</code>
              </p>
            </td><td>
              <p>
                Obtain a handler&#8217;s associated allocator.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="literal">executor</code>
              </p>
            </td><td>
              <p>
                Class template <code class="literal">execution_context</code>
              </p>
            </td><td>
              <p>
                Base class for execution context types.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="literal">executor</code>
              </p>
            </td><td>
              <p>
                Class template <code class="literal">associated_executor</code>
              </p>
            </td><td>
              <p>
                Used to determine a handler&#8217;s associated executor.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="literal">executor</code>
              </p>
            </td><td>
              <p>
                Function <code class="literal">get_associated_executor</code>
              </p>
            </td><td>
              <p>
                Obtain a handler&#8217;s associated executor.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="literal">executor</code>
              </p>
            </td><td>
              <p>
                Class template <code class="literal">executor_binder</code>
              </p>
            </td><td>
              <p>
                Associates an executor with an object.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="literal">executor</code>
              </p>
            </td><td>
              <p>
                Function <code class="literal">bind_executor</code>
              </p>
            </td><td>
              <p>
                Associate an executor with an object.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="literal">executor</code>
              </p>
            </td><td>
              <p>
                Class template <code class="literal">executor_work_guard</code>
              </p>
            </td><td>
              <p>
                Tracks outstanding work against an executor.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="literal">executor</code>
              </p>
            </td><td>
              <p>
                Function <code class="literal">make_work_guard</code>
              </p>
            </td><td>
              <p>
                Create work to track an outstanding operation.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="literal">executor</code>
              </p>
            </td><td>
              <p>
                Class <code class="literal">system_executor</code>
              </p>
            </td><td>
              <p>
                Executor representing all threads in system.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="literal">executor</code>
              </p>
            </td><td>
              <p>
                Class <code class="literal">system_context</code>
              </p>
            </td><td>
              <p>
                The execution context underlying <code class="literal">system_executor</code>
                instances.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="literal">executor</code>
              </p>
            </td><td>
              <p>
                Class <code class="literal">executor</code>
              </p>
            </td><td>
              <p>
                Polymorphic wrapper for executors.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="literal">executor</code>
              </p>
            </td><td>
              <p>
                Functions <code class="literal">dispatch</code>, <code class="literal">post</code> and
                <code class="literal">defer</code>
              </p>
            </td><td>
              <p>
                Execute a function object.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="literal">executor</code>
              </p>
            </td><td>
              <p>
                Class template <code class="literal">strand</code>
              </p>
            </td><td>
              <p>
                Executor adapter that runs function objects non-concurrently, in
                FIFO order, and without blocking the submitter if the FIFO queue
                is non-empty.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="literal">executor</code>
              </p>
            </td><td>
              <p>
                Class template <code class="literal">use_future_t</code>
              </p>
            </td><td>
              <p>
                Completion token to enable futures with asynchronous operations.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="literal">executor</code>
              </p>
            </td><td>
              <p>
                Class template specialization of <code class="literal">async_result</code>
                for <code class="literal">packaged_task</code>
              </p>
            </td><td>
              <p>
                Supports use of packaged_task with dispatch, post, defer, and asynchronous
                operations.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="literal">thread_pool</code>
              </p>
            </td><td>
              <p>
                Class <code class="literal">thread_pool</code>
              </p>
            </td><td>
              <p>
                A fixed size thread pool.
              </p>
            </td></tr><tr><td>
              <p>
                <code class="literal">loop_scheduler</code>
              </p>
            </td><td>
              <p>
                Class <code class="literal">loop_scheduler</code>
              </p>
            </td><td>
              <p>
                A thread pool where threads are explicitly donated by the caller.
              </p>
            </td></tr></tbody></table></div></div><div class="section" title="8.&#160;On the naming of executors"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="executors.on_the_naming_of_executors"></a>8.&#160;On the naming of executors</h2></div></div></div><p>
      There has been some confusion due to the reuse of the term <span class="emphasis"><em>executor</em></span>
      in N3785 and successors and this proposal, but with slightly different meanings.
      In N3785, an "executor" refers to a heavyweight, non-copyable object,
      such as a thread pool. In this proposal, an "executor" is a lightweight,
      copyable policy object. This is distinct from a heavyweight object such as
      a thread pool, which is known as an "execution context".
    </p><p>
      N3785's API is superficially similar to Java executors, so it is interesting
      to examine the Java prior art in this area. What we find is that this approach
      misses a key concept: the separation of <code class="computeroutput"><span class="identifier">Executor</span></code>
      and <code class="computeroutput"><span class="identifier">ExecutorService</span></code>. On the
      other hand, it turns out that this proposal's "executor" mirrors
      the concept <span class="emphasis"><em>and</em></span> terminology of Java executors.
    </p><p>
      Let us start by reviewing a couple of the core interfaces of the Java executor
      framework: <span class="emphasis"><em><a href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html" target="_top">http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html</a></em></span>
    </p><p>
      First, we have interface <code class="computeroutput"><span class="identifier">Executor</span></code>.
      This interface provides a way of submitting a <code class="computeroutput"><span class="identifier">Runnable</span></code>
      (i.e. the equivalent of a function object) for execution, and it decouples
      the submission from the concrete mechanism which runs the function.
    </p><p>
      Second, we have interface <code class="computeroutput"><span class="identifier">ExecutorService</span></code>.
      This extends <code class="computeroutput"><span class="identifier">Executor</span></code>, i.e.
      <code class="computeroutput"><span class="identifier">ExecutorService</span></code> <span class="emphasis"><em>is-a</em></span>
      Executor. It adds some additional functionality, such as the ability to request
      that it be shut down.
    </p><p>
      A thread pool <span class="emphasis"><em>is-a</em></span> <code class="computeroutput"><span class="identifier">ExecutorService</span></code>.
      A fork/join pool <span class="emphasis"><em>is-a</em></span> <code class="computeroutput"><span class="identifier">ExecutorService</span></code>.
      An <code class="computeroutput"><span class="identifier">ExecutorService</span></code> represents
      a heavyweight entity where <code class="computeroutput"><span class="identifier">Runnable</span></code>
      items are run.
    </p><p>
      A <code class="computeroutput"><span class="identifier">SerialExecutor</span></code> <span class="emphasis"><em>is-a</em></span>
      <code class="computeroutput"><span class="identifier">Executor</span></code>. A thread-per-task
      executor <span class="emphasis"><em>is-a</em></span> <code class="computeroutput"><span class="identifier">Executor</span></code>.
      An executor represents a policy. Where there is a customisation point (as in
      the <code class="computeroutput"><span class="identifier">ExecutorCompletionService</span></code>
      class) it is specified as an <code class="computeroutput"><span class="identifier">Executor</span></code>.
    </p><p>
      When we want to create our own policy, we do it by implementing the <code class="computeroutput"><span class="identifier">Executor</span></code> interface. Our <code class="computeroutput"><span class="identifier">Executor</span></code>
      policy object can be short lived, or it can be long lived. As we are using
      Java, the object is newed and we let the garbage collector take care of it.
      In fact, we don't really have a choice.
    </p><p>
      Java is not C++. Java references are not C++ references, nor are they C++ pointers.
      We do not have the garbage collector to clean up after us. Yet, and this is
      especially true of concurrent code, correctly managing object lifetime is critical.
      How do we address this in C++? The idiomatic approach is to use value semantics.
    </p><p>
      Thus our <code class="computeroutput"><span class="identifier">Executor</span></code> policy object
      should use value semantics. We should be able to copy it and move it freely.
      Where a particular concrete <code class="computeroutput"><span class="identifier">Executor</span></code>
      uses some allocated resource, the constructors and destructors can manage the
      resource lifetime, just as we do in other standard library components.
    </p><p>
      Of course, we do want to be able to use a heavyweight thread pool as an <code class="computeroutput"><span class="identifier">Executor</span></code>. In Java, the thread pool <span class="emphasis"><em>is-a</em></span>
      <code class="computeroutput"><span class="identifier">ExecutorService</span></code> which <span class="emphasis"><em>is-a</em></span>
      <code class="computeroutput"><span class="identifier">Executor</span></code>, so we are able to
      use the heavyweight object in the same way as a lightweight one. Once again,
      this is because of Java's reference semantics, where basically all objects
      are treated the same, whether light or heavy.
    </p><p>
      In C++, however, our heavyweight thread pool may be best represented by a non-copyable
      type. This presents a challenge: how do we establish a pattern where we can
      pass either a noncopyable type or a type with value semantics? That is, how
      can we have an interface where we can pass either a heavyweight <code class="computeroutput"><span class="identifier">ExecutorService</span></code> or a lightweight <code class="computeroutput"><span class="identifier">Executor</span></code>?
    </p><p>
      The solution is to change the relationship between <code class="computeroutput"><span class="identifier">ExecutorService</span></code>
      and <code class="computeroutput"><span class="identifier">Executor</span></code>. Rather than saying
      an <code class="computeroutput"><span class="identifier">ExecutorService</span></code> <span class="emphasis"><em>is-a</em></span>
      <code class="computeroutput"><span class="identifier">Executor</span></code>, we instead say an
      <code class="computeroutput"><span class="identifier">ExecutorService</span></code> <span class="bold"><strong><span class="emphasis"><em>has-a</em></span></strong></span>
      <code class="computeroutput"><span class="identifier">Executor</span></code>. Every <code class="computeroutput"><span class="identifier">ExecutorService</span></code> has an associated lightweight
      <code class="computeroutput"><span class="identifier">Executor</span></code> policy which encapsulates
      the submission logic. This lightweight <code class="computeroutput"><span class="identifier">Executor</span></code>
      provides the necessary value semantics.
    </p><p>
      Thus we can see that this proposal's "executor" is in fact the same
      concept as the Java <code class="computeroutput"><span class="identifier">Executor</span></code>.
      It is just that it is packaged in a way that is more idiomatic C++, i.e. it
      uses value semantics. This proposal's "execution context" concept
      is the equivalent of Java's <code class="computeroutput"><span class="identifier">ExecutorService</span></code>.
      The executor is the "how", a policy, and it logically performs the
      execution. The execution context or <code class="computeroutput"><span class="identifier">ExecutorService</span></code>
      is the "where", a venue if you like.
    </p><p>
      As we are using C++, and not Java, we get the same level of abstraction but
      with the benefits of compile time polymorphism, inlining, control over memory
      use, and using fewer allocations (i.e. we create less garbage). The reasons
      we are using C++ in the first place.
    </p><p>
      As we can see, the separation of executor from execution context clearly exists
      in the prior art represented by Java. However, this proposal's design is derived
      from Boost.Asio, and is very much driven by what is required to make asynchronous
      operations work, but with a desire to have a clean separation of concerns.
      The Java executors framework did not inform the design, yet it is not surprising
      that Java represents an example of convergent evolution, once we make a deeper
      analysis of the library.
    </p></div><div class="section" title="9.&#160;On the need for dispatch, post and defer"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="executors.on_the_need_for_dispatch__post_and_defer"></a>9.&#160;On the need for dispatch, post and defer</h2></div></div></div><p>
      Let us take another look at the specification of the Java <code class="computeroutput"><span class="identifier">Executor</span></code>
      class and its <code class="computeroutput"><span class="identifier">execute</span></code> method:
      <span class="emphasis"><em><a href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executor.html" target="_top">http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executor.html</a></em></span>
    </p><p>
      It says:
    </p><div class="blockquote"><blockquote class="blockquote"><p>
        <code class="computeroutput"><span class="keyword">void</span> <span class="identifier">execute</span><span class="special">(</span><span class="identifier">Runnable</span> <span class="identifier">command</span><span class="special">)</span></code><br>
        <br> <span class="emphasis"><em>Executes the given command at some time in the future. The
        command may execute in a new thread, in a pooled thread, or in the calling
        thread, at the discretion of the Executor implementation.</em></span>
      </p></blockquote></div><p>
      Note that the wording includes "in the calling thread". In fact,
      the specification of the execute method is essentially the same as the <code class="computeroutput"><span class="identifier">dispatch</span></code> function of this proposal.
    </p><p>
      As it is the only available <code class="computeroutput"><span class="identifier">Executor</span></code>
      method, this specification of <code class="computeroutput"><span class="identifier">execute</span></code>
      is a problem. Clearly there are times when we want to guarantee that a function
      will <span class="emphasis"><em>not</em></span> run in the calling thread, such as when we want
      launch a long running function. Unfortunately, if we are using an <code class="computeroutput"><span class="identifier">Executor</span></code> in a polymorphic context we have
      no way of knowing what behaviour we will get. We have to know the concrete
      executor type to ensure that it doesn't run in the calling thread.
    </p><p>
      Thus, we wish to introduce a function with slightly different semantics:
    </p><div class="blockquote"><blockquote class="blockquote"><p>
        <span class="emphasis"><em>Executes the given command at some time in the future. The command
        may execute in a new thread, in a pooled thread, at the discretion of the
        Executor implementation.</em></span>
      </p></blockquote></div><p>
      This is the <code class="computeroutput"><span class="identifier">post</span></code> function of
      this proposal, and it lets us as the caller ensure that a function does not
      run in the calling thread.
    </p><p>
      However, this does not obviate the need for the original semantics (i.e. the
      current Java semantics). There are times when it is to our advantage to allow
      a function to run in the calling thread. Some examples:
    </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
          When using a strand (or a serial executor, in Java terminology) to ensure
          non-concurrent function execution. If the strand is not contended, we want
          to execute the function in the current thread. This will minimise latency
          and avoid the cost of a context switch.
        </li><li class="listitem">
          At the end of an asynchronous operation. We are unwrapping layers of composition
          and handing the result back through a stack of callbacks. A callback needs
          to run on its correct executor, but we do not want to unnecessarily incur
          a context switch or a cycle through the scheduler, as doing so significantly
          adds to the latency in processing the event.
        </li></ul></div><p>
      Interestingly, the specification of <code class="computeroutput"><span class="identifier">future</span><span class="special">::</span><span class="identifier">then</span></code> (now
      removed from the concurrency TS) that took an executor would also suffer from
      this extra cost unless it had access to dispatch semantics.
    </p><p>
      The <code class="computeroutput"><span class="identifier">defer</span></code> operation, like
      <code class="computeroutput"><span class="identifier">post</span></code>, does not allow the function
      to run in the calling thread. Where it differs is in the expression of the
      intent of the caller. Using <code class="computeroutput"><span class="identifier">defer</span></code>
      states that there is a relationship between the caller and callee, such as
      being consecutive links in a chain of function objects. An executor can make
      use of this to do smarter, more efficient scheduling.
    </p><p>
      For example, consider a chain of asynchronous read operations on a socket:
    </p><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">read_loop</span><span class="special">(</span><span class="identifier">Socket</span> <span class="identifier">socket</span><span class="special">,</span> <span class="identifier">Buffer</span> <span class="identifier">buffer</span><span class="special">)</span>
<span class="special">{</span>
  <span class="identifier">async_read</span><span class="special">(</span><span class="identifier">socket</span><span class="special">,</span> <span class="identifier">buffer</span><span class="special">,</span>
    <span class="special">[&amp;](</span><span class="identifier">error_code</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">n</span><span class="special">)</span> <span class="special">{</span>
      <span class="identifier">process_data</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">,</span> <span class="identifier">n</span><span class="special">);</span>
      <span class="identifier">read_loop</span><span class="special">(</span><span class="identifier">socket</span><span class="special">,</span> <span class="identifier">buffer</span><span class="special">);</span>
    <span class="special">});</span>
<span class="special">}</span>
</pre><p>
      where an individual read operation is implemented something like this:
    </p><pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Handler</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">async_read</span><span class="special">(</span><span class="identifier">Socket</span> <span class="identifier">socket</span><span class="special">,</span> <span class="identifier">Buffer</span> <span class="identifier">buffer</span><span class="special">,</span> <span class="identifier">Handler</span> <span class="identifier">handler</span><span class="special">)</span>
<span class="special">{</span>
  <span class="comment">// Perform a speculative read first.</span>
  <span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">;</span>
  <span class="identifier">size_t</span> <span class="identifier">n</span> <span class="special">=</span> <span class="identifier">non_blocking_read</span><span class="special">(</span><span class="identifier">socket</span><span class="special">,</span> <span class="identifier">buffer</span><span class="special">,</span> <span class="identifier">ec</span><span class="special">);</span>
  <span class="keyword">if</span> <span class="special">(</span><span class="identifier">ec</span> <span class="special">!=</span> <span class="identifier">would_block</span><span class="special">)</span>
  <span class="special">{</span>
    <span class="comment">// Read completed immediately, post handler.</span>
    <span class="identifier">ex</span> <span class="special">=</span> <span class="identifier">get_associated_executor</span><span class="special">(</span><span class="identifier">handler</span><span class="special">);</span>
    <span class="identifier">post</span><span class="special">(</span><span class="identifier">ex</span><span class="special">,</span> <span class="special">[=]{</span> <span class="identifier">handler</span><span class="special">(</span><span class="identifier">ec</span><span class="special">,</span> <span class="identifier">n</span><span class="special">);</span> <span class="special">});</span>
  <span class="special">}</span>
  <span class="keyword">else</span>
  <span class="special">{</span>
    <span class="comment">// Wait for socket to become readable.</span>
    <span class="comment">// ...</span>
  <span class="special">}</span>
<span class="special">}</span>
</pre><p>
      In certain circumstances the read operation will always complete immediately,
      such as when the data is already available in the kernel buffers. When this
      occurs, the sequence of operations is essentially equivalent to:
    </p><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">read_loop</span><span class="special">(</span><span class="identifier">socket</span><span class="special">,</span> <span class="identifier">buffer</span><span class="special">)</span>
<span class="special">{</span>
  <span class="comment">// ...</span>
  <span class="identifier">ex</span><span class="special">.</span><span class="identifier">post</span><span class="special">([&amp;]{</span> <span class="comment">// #1 <a name="post1"></a></span>
      <span class="identifier">read_loop</span><span class="special">(</span><span class="identifier">socket</span><span class="special">,</span> <span class="identifier">buffer</span><span class="special">);</span>
    <span class="special">});</span>
  <span class="comment">// ...</span>
<span class="special">}</span>
</pre><p>
      Let us assume that our executor <code class="computeroutput"><span class="identifier">ex</span></code>
      uses a thread pool with a mutex-protected queue:
    </p><pre class="programlisting"><span class="keyword">class</span> <span class="identifier">my_thread_pool</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
  <span class="keyword">class</span> <span class="identifier">executor_type</span>
  <span class="special">{</span>
  <span class="keyword">public</span><span class="special">:</span>
    <span class="comment">// ...</span>

    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
    <span class="keyword">void</span> <span class="identifier">post</span><span class="special">(</span><span class="identifier">Func</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Alloc</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">)</span>
    <span class="special">{</span>
      <span class="keyword">auto</span> <span class="identifier">p</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocate_shared</span><span class="special">&lt;</span><span class="identifier">item</span><span class="special">&lt;</span><span class="identifier">Func</span><span class="special">&gt;&gt;(</span><span class="identifier">a</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">lock_guard</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">mutex</span><span class="special">&gt;</span> <span class="identifier">lock</span><span class="special">(</span><span class="identifier">pool_</span><span class="special">.</span><span class="identifier">mutex_</span><span class="special">);</span> <span class="comment">// #2 <a name="post2"></a></span>
      <span class="identifier">pool_</span><span class="special">.</span><span class="identifier">queue_</span><span class="special">.</span><span class="identifier">push_back</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">p</span><span class="special">));</span> <span class="comment">// #3 <a name="post3"></a></span>
      <span class="identifier">pool_</span><span class="special">.</span><span class="identifier">condition_</span><span class="special">.</span><span class="identifier">notify_one</span><span class="special">();</span> <span class="comment">// #4 <a name="post4"></a></span>
      <span class="comment">// #5 <a name="post5"></a></span>
    <span class="special">}</span>

    <span class="comment">// ...</span>
  <span class="special">};</span>

  <span class="comment">// ...</span>

  <span class="keyword">void</span> <span class="identifier">run</span><span class="special">()</span>
  <span class="special">{</span>
    <span class="keyword">for</span> <span class="special">(;;)</span>
    <span class="special">{</span>
      <span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_lock</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">mutex</span><span class="special">&gt;</span> <span class="identifier">lock</span><span class="special">(</span><span class="identifier">mutex_</span><span class="special">);</span> <span class="comment">// #6 <a name="post6"></a></span>
      <span class="identifier">condition_</span><span class="special">.</span><span class="identifier">wait</span><span class="special">(</span><span class="identifier">lock</span><span class="special">,</span> <span class="special">[&amp;]{</span> <span class="special">!</span><span class="identifier">queue_</span><span class="special">.</span><span class="identifier">empty</span><span class="special">();</span> <span class="special">});</span>
      <span class="keyword">auto</span> <span class="identifier">p</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">queue_</span><span class="special">.</span><span class="identifier">front</span><span class="special">()));</span> <span class="comment">// #7 <a name="post7"></a></span>
      <span class="identifier">queue_</span><span class="special">.</span><span class="identifier">pop_front</span><span class="special">();</span>
      <span class="identifier">lock</span><span class="special">.</span><span class="identifier">unlock</span><span class="special">();</span> <span class="comment">// #8 <a name="post8"></a></span>
      <span class="identifier">p</span><span class="special">-&gt;</span><span class="identifier">execute_</span><span class="special">(</span><span class="identifier">p</span><span class="special">);</span> <span class="comment">// #9 <a name="post9"></a></span>
    <span class="special">}</span>
  <span class="special">}</span>

<span class="keyword">private</span><span class="special">:</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">mutex</span> <span class="identifier">mutex_</span><span class="special">;</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">condition_variable</span> <span class="identifier">condition_</span><span class="special">;</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">deque</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span><span class="identifier">item_base</span><span class="special">&gt;&gt;</span> <span class="identifier">queue_</span><span class="special">;</span>
<span class="special">};</span>
</pre><p>
      There are two performance issues at play here. First, each "cycle"
      of <code class="computeroutput"><span class="identifier">read_loop</span></code> involves two lock/unlock
      pairs. Second, a condition variable may be used to wake a sleeping thread when
      the queue is non-empty. If we step through the code we will see the following:
    </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
          <a class="link" href="#post6">#6</a> &#8212; lock
        </li><li class="listitem">
          <a class="link" href="#post7">#7</a> &#8212; dequeue <code class="computeroutput"><span class="identifier">read_loop</span></code>
        </li><li class="listitem">
          <a class="link" href="#post8">#8</a> &#8212; unlock
        </li><li class="listitem">
          <a class="link" href="#post9">#9</a> &#8212; call <code class="computeroutput"><span class="identifier">read_loop</span></code>
          <div class="itemizedlist"><ul class="itemizedlist" type="circle"><li class="listitem">
                <a class="link" href="#post1">#1</a> &#8212; call <code class="computeroutput"><span class="identifier">post</span></code>
                <div class="itemizedlist"><ul class="itemizedlist" type="square"><li class="listitem">
                      <a class="link" href="#post2">#2</a> &#8212; lock
                    </li><li class="listitem">
                      <a class="link" href="#post3">#3</a> &#8212; enqueue <code class="computeroutput"><span class="identifier">read_loop</span></code>
                    </li><li class="listitem">
                      <a class="link" href="#post4">#4</a> &#8212; notify
                    </li><li class="listitem">
                      <a class="link" href="#post5">#5</a> &#8212; unlock
                    </li></ul></div>
              </li></ul></div>
        </li><li class="listitem">
          <span class="emphasis"><em>(start of next cycle)</em></span>
        </li><li class="listitem">
          <a class="link" href="#post6">#6</a> &#8212; lock
        </li><li class="listitem">
          <a class="link" href="#post7">#7</a> &#8212; dequeue <code class="computeroutput"><span class="identifier">read_loop</span></code>
        </li><li class="listitem">
          <a class="link" href="#post8">#8</a> &#8212; unlock
        </li><li class="listitem">
          <a class="link" href="#post9">#9</a> &#8212; call <code class="computeroutput"><span class="identifier">read_loop</span></code>
        </li><li class="listitem">
          ...
        </li></ul></div><p>
      On the other hand, with <code class="computeroutput"><span class="identifier">defer</span></code>
      we are telling the executor that the submitted function is a continuation of
      the current one. That is, the executor does not have to eagerly schedule the
      function because we have told it that one function follows the other.
    </p><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">read_loop</span><span class="special">(</span><span class="identifier">socket</span><span class="special">,</span> <span class="identifier">buffer</span><span class="special">)</span>
<span class="special">{</span>
  <span class="comment">// ...</span>
  <span class="identifier">ex</span><span class="special">.</span><span class="identifier">defer</span><span class="special">([&amp;]{</span> <span class="comment">// #1 <a name="defer1"></a></span>
      <span class="identifier">read_loop</span><span class="special">(</span><span class="identifier">socket</span><span class="special">,</span> <span class="identifier">buffer</span><span class="special">);</span>
    <span class="special">});</span>
  <span class="comment">// ...</span>
<span class="special">}</span>

<span class="keyword">class</span> <span class="identifier">my_thread_pool</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
  <span class="keyword">class</span> <span class="identifier">executor_type</span>
  <span class="special">{</span>
  <span class="keyword">public</span><span class="special">:</span>
    <span class="comment">// ...</span>

    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Alloc</span><span class="special">&gt;</span>
    <span class="keyword">void</span> <span class="identifier">defer</span><span class="special">(</span><span class="identifier">Func</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Alloc</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">)</span>
    <span class="special">{</span>
      <span class="keyword">if</span> <span class="special">(</span><span class="identifier">pool_</span><span class="special">.</span><span class="identifier">thread_local_queue_</span><span class="special">)</span>
      <span class="special">{</span>
        <span class="keyword">auto</span> <span class="identifier">p</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocate_shared</span><span class="special">&lt;</span><span class="identifier">item</span><span class="special">&lt;</span><span class="identifier">Func</span><span class="special">&gt;&gt;(</span><span class="identifier">a</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">pool_</span><span class="special">.</span><span class="identifier">thread_local_queue_</span><span class="special">-&gt;</span><span class="identifier">push_back</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">p</span><span class="special">));</span> <span class="comment">// #2 <a name="defer2"></a></span>
      <span class="special">}</span>
      <span class="keyword">else</span>
        <span class="identifier">post</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">a</span><span class="special">);</span>
    <span class="special">}</span>

    <span class="comment">// ...</span>
  <span class="special">};</span>

  <span class="comment">// ...</span>

  <span class="keyword">void</span> <span class="identifier">run</span><span class="special">()</span>
  <span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">deque</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span><span class="identifier">item_base</span><span class="special">&gt;&gt;</span> <span class="identifier">local_queue</span><span class="special">;</span>
    <span class="identifier">thread_local_queue_</span> <span class="special">=</span> <span class="special">&amp;</span><span class="identifier">local_queue</span><span class="special">;</span>
    <span class="keyword">for</span> <span class="special">(;;)</span>
    <span class="special">{</span>
      <span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_lock</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">mutex</span><span class="special">&gt;</span> <span class="identifier">lock</span><span class="special">(</span><span class="identifier">mutex_</span><span class="special">);</span> <span class="comment">// #3 <a name="defer3"></a></span>
      <span class="keyword">while</span> <span class="special">(!</span><span class="identifier">local_queue</span><span class="special">.</span><span class="identifier">empty</span><span class="special">())</span> <span class="comment">// #4 <a name="defer4"></a></span>
      <span class="special">{</span>
        <span class="identifier">queue_</span><span class="special">.</span><span class="identifier">push</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">local_queue</span><span class="special">.</span><span class="identifier">front</span><span class="special">()));</span>
        <span class="identifier">local_queue</span><span class="special">.</span><span class="identifier">pop_front</span><span class="special">();</span>
      <span class="special">}</span>
      <span class="identifier">condition_</span><span class="special">.</span><span class="identifier">wait</span><span class="special">(</span><span class="identifier">lock</span><span class="special">,</span> <span class="special">[&amp;]{</span> <span class="special">!</span><span class="identifier">queue_</span><span class="special">.</span><span class="identifier">empty</span><span class="special">();</span> <span class="special">});</span>
      <span class="keyword">auto</span> <span class="identifier">p</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">queue_</span><span class="special">.</span><span class="identifier">front</span><span class="special">()));</span> <span class="comment">// #5 <a name="defer5"></a></span>
      <span class="identifier">queue_</span><span class="special">.</span><span class="identifier">pop_front</span><span class="special">();</span>
      <span class="identifier">lock</span><span class="special">.</span><span class="identifier">unlock</span><span class="special">();</span> <span class="comment">// #6 <a name="defer6"></a></span>
      <span class="identifier">p</span><span class="special">-&gt;</span><span class="identifier">execute_</span><span class="special">(</span><span class="identifier">p</span><span class="special">);</span> <span class="comment">// #7 <a name="defer7"></a></span>
    <span class="special">}</span>
  <span class="special">}</span>

<span class="keyword">private</span><span class="special">:</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">mutex</span> <span class="identifier">mutex_</span><span class="special">;</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">condition_variable</span> <span class="identifier">condition_</span><span class="special">;</span>
  <span class="identifier">std</span><span class="special">::</span><span class="identifier">deque</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span><span class="identifier">item_base</span><span class="special">&gt;&gt;</span> <span class="identifier">queue_</span><span class="special">;</span>
  <span class="keyword">static</span> <span class="keyword">thread_local</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">deque</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span><span class="identifier">item_base</span><span class="special">&gt;&gt;*</span> <span class="identifier">thread_local_queue_</span><span class="special">;</span>
<span class="special">};</span>
</pre><p>
      Now when we step through the code:
    </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
          <a class="link" href="#defer3">#3</a> &#8212; lock
        </li><li class="listitem">
          <a class="link" href="#defer4">#4</a> &#8212; copy contents of thread-local queue to
          main queue
        </li><li class="listitem">
          <a class="link" href="#defer5">#5</a> &#8212; dequeue <code class="computeroutput"><span class="identifier">read_loop</span></code>
        </li><li class="listitem">
          <a class="link" href="#defer6">#6</a> &#8212; unlock
        </li><li class="listitem">
          <a class="link" href="#defer7">#7</a> &#8212; call <code class="computeroutput"><span class="identifier">read_loop</span></code>
          <div class="itemizedlist"><ul class="itemizedlist" type="circle"><li class="listitem">
                <a class="link" href="#defer1">#1</a> &#8212; call <code class="computeroutput"><span class="identifier">defer</span></code>
                <div class="itemizedlist"><ul class="itemizedlist" type="square"><li class="listitem">
                      <a class="link" href="#defer2">#2</a> &#8212; enqueue <code class="computeroutput"><span class="identifier">read_loop</span></code>
                      to thread-local queue
                    </li></ul></div>
              </li></ul></div>
        </li><li class="listitem">
          <span class="emphasis"><em>(start of next cycle)</em></span>
        </li><li class="listitem">
          <a class="link" href="#defer3">#3</a> &#8212; lock
        </li><li class="listitem">
          <a class="link" href="#defer4">#4</a> &#8212; copy contents of thread-local queue to
          main queue
        </li><li class="listitem">
          <a class="link" href="#defer5">#5</a> &#8212; dequeue <code class="computeroutput"><span class="identifier">read_loop</span></code>
        </li><li class="listitem">
          <a class="link" href="#defer6">#6</a> &#8212; unlock
        </li><li class="listitem">
          <a class="link" href="#defer7">#7</a> &#8212; call <code class="computeroutput"><span class="identifier">read_loop</span></code>
        </li><li class="listitem">
          ...
        </li></ul></div><p>
      we see that we have eliminated one lock/unlock pair, and we also no longer
      need to wake another thread. We are able to do this because of the additional
      information imparted by <code class="computeroutput"><span class="identifier">defer</span></code>.
    </p><p>
      On recent hardware we can observe an uncontended lock/unlock cost of some 10
      to 15 nanoseconds, compared with 1 to 2 nanoseconds for accessing a thread-local
      queue. There is also a significant (and often larger) benefit in avoiding the
      unnecessary thread wakeup and the ensuing lock contention, particularly when
      dealing with bursty traffic profiles. Either way, this is a latency win.
    </p><p>
      With asynchronous operations, the rules are that if an operation completes
      immediately it posts the result (rather than dispatch, which may result in
      unfairness, starvation or stack overflow). If it finishes later, it dispatches
      the result (to minimise latency).
    </p><p>
      By default, an individual low-level asynchronous operation, such as <code class="computeroutput"><span class="identifier">async_read</span></code> shown above, doesn't know if the
      operation represents a continuation of the current function, or a new fork
      in the control flow. Either one is possible, so we conservatively assume that
      every operation represents a new fork and use <code class="computeroutput"><span class="identifier">post</span></code>.
    </p><p>
      However, once we move to a higher layer of abstraction, like a composed operation
      to read a message frame, we can start to make certain assertions. We know that
      within the operation it consists of a single chain of asynchronous reads.
    </p><p>
      As an example, let us consider a hypothetical composed operation to read a
      message frame, implemented in terms of <code class="computeroutput"><span class="identifier">async_read</span></code>
      above. Each message frame consists of a header, a body in several chunks, and
      a trailer. In this scenario, the header and body are immediately available
      in the kernel buffers, but we have to wait for the trailer to arrive. The sequence
      of executor operations used by the asynchronous chain looks like this:
    </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
          header available immediately &#8594; <code class="computeroutput"><span class="identifier">post</span><span class="special">()</span></code>
        </li><li class="listitem">
          first body chunk available immediately &#8594; <code class="computeroutput"><span class="identifier">post</span><span class="special">()</span></code>
        </li><li class="listitem">
          second body chunk available immediately &#8594; <code class="computeroutput"><span class="identifier">post</span><span class="special">()</span></code>
        </li><li class="listitem">
          <span class="emphasis"><em>... waiting for trailer ...</em></span>
        </li><li class="listitem">
          trailer available &#8594; <code class="computeroutput"><span class="identifier">dispatch</span><span class="special">()</span></code>
        </li></ul></div><p>
      One of the motivating reasons for having lightweight, copyable executors, distinct
      from the execution context, is that they let us remap the executor operations
      as required. Thus, within the composed operation we can remap <code class="computeroutput"><span class="identifier">post</span></code> to <code class="computeroutput"><span class="identifier">defer</span></code>.
      We can do this with a lightweight wrapper around the composed operation's handler's
      associated executor:
    </p><pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">remap_post_to_defer</span>
<span class="special">{</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">A</span><span class="special">&gt;</span>
  <span class="keyword">void</span> <span class="identifier">post</span><span class="special">(</span><span class="identifier">F</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">A</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">)</span>
  <span class="special">{</span>
    <span class="identifier">ex_</span><span class="special">.</span><span class="identifier">defer</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">a</span><span class="special">);</span>
  <span class="special">}</span>
  <span class="special">...</span>
  <span class="identifier">Executor</span> <span class="identifier">ex_</span><span class="special">;</span>
<span class="special">};</span>
</pre><p>
      We can then apply this wrapper to optimise the intermediate steps of the chain:
    </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
          header available immediately &#8594; <code class="computeroutput"><span class="identifier">post</span><span class="special">()</span></code>
        </li><li class="listitem">
          first body chunk available immediately &#8594; <code class="computeroutput"><span class="identifier">defer</span><span class="special">()</span></code>
        </li><li class="listitem">
          second body chunk available immediately &#8594; <code class="computeroutput"><span class="identifier">defer</span><span class="special">()</span></code>
        </li><li class="listitem">
          <span class="emphasis"><em>... waiting for trailer ...</em></span>
        </li><li class="listitem">
          trailer available &#8594; <code class="computeroutput"><span class="identifier">dispatch</span><span class="special">()</span></code>
        </li></ul></div><p>
      If we had a limited vocabulary that only consisted of dispatch:
    </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
          header available immediately &#8594; <code class="computeroutput"><span class="identifier">dispatch</span><span class="special">()</span></code>
        </li><li class="listitem">
          first body chunk available immediately &#8594; <code class="computeroutput"><span class="identifier">dispatch</span><span class="special">()</span></code>
        </li><li class="listitem">
          second body chunk available immediately &#8594; <code class="computeroutput"><span class="identifier">dispatch</span><span class="special">()</span></code>
        </li><li class="listitem">
          <span class="emphasis"><em>... waiting for trailer ...</em></span>
        </li><li class="listitem">
          trailer available &#8594; <code class="computeroutput"><span class="identifier">dispatch</span><span class="special">()</span></code>
        </li></ul></div><p>
      then traffic bursts can lead to unfairness and starvation. We are susceptible
      to denial of service attacks.
    </p><p>
      If our vocabulary only consisted of post:
    </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
          header available immediately &#8594; <code class="computeroutput"><span class="identifier">post</span><span class="special">()</span></code>
        </li><li class="listitem">
          first body chunk available immediately &#8594; <code class="computeroutput"><span class="identifier">post</span><span class="special">()</span></code>
        </li><li class="listitem">
          second body chunk available immediately &#8594; <code class="computeroutput"><span class="identifier">post</span><span class="special">()</span></code>
        </li><li class="listitem">
          <span class="emphasis"><em>... waiting for trailer ...</em></span>
        </li><li class="listitem">
          trailer available &#8594; <code class="computeroutput"><span class="identifier">post</span><span class="special">()</span></code>
        </li></ul></div><p>
      then every operation in the chain can incur otherwise avoidable synchronisation
      costs, context switches, and cycles through the scheduler, resulting in higher
      latency.
    </p><p>
      If our vocabulary only consisted of defer:
    </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
          header available immediately &#8594; <code class="computeroutput"><span class="identifier">defer</span><span class="special">()</span></code>
        </li><li class="listitem">
          first body chunk available immediately &#8594; <code class="computeroutput"><span class="identifier">defer</span><span class="special">()</span></code>
        </li><li class="listitem">
          second body chunk available immediately &#8594; <code class="computeroutput"><span class="identifier">defer</span><span class="special">()</span></code>
        </li><li class="listitem">
          <span class="emphasis"><em>... waiting for trailer ...</em></span>
        </li><li class="listitem">
          trailer available &#8594; <code class="computeroutput"><span class="identifier">defer</span><span class="special">()</span></code>
        </li></ul></div><p>
      then we almost get away with it, apart from the additional latency introduced
      by <code class="computeroutput"><span class="identifier">defer</span></code> at the end of the
      operation. However, we are also limiting the opportunities for concurrency.
      This may not be an issue in this example with a single chain of operations,
      but can be a problem where your asynchronous control flow really does fork,
      such as in a typical accept "loop":
    </p><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">handle_accept</span><span class="special">()</span>
<span class="special">{</span>
  <span class="identifier">new_socket</span><span class="special">-&gt;</span><span class="identifier">start</span><span class="special">();</span> <span class="comment">// starts asynchronous reads and writes</span>
  <span class="identifier">async_accept</span><span class="special">(...,</span> <span class="special">&amp;</span><span class="identifier">handle_accept</span><span class="special">);</span> <span class="comment">// accepts next connection</span>
<span class="special">}</span>
</pre><p>
      Thus we need all three operations to complete the set:
    </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
          <code class="computeroutput"><span class="identifier">post</span></code> &#8212; the default choice,
          guaranteeing non-blocking calls and maximising concurrency
        </li><li class="listitem">
          <code class="computeroutput"><span class="identifier">dispatch</span></code> &#8212; for minimising
          latency when we are prepared to accept blocking
        </li><li class="listitem">
          <code class="computeroutput"><span class="identifier">defer</span></code> &#8212; to link sequences
          of related operations
        </li></ul></div><p>
      Note that, when implementing the executor type requirements, it is perfectly
      fine to start by implementing <code class="computeroutput"><span class="identifier">dispatch</span></code>
      and <code class="computeroutput"><span class="identifier">defer</span></code> in terms of <code class="computeroutput"><span class="identifier">post</span></code>. This is in keeping with the specified
      semantics. Then, we can optimise the implementation of these functions as we
      are able to.
    </p><p>
      However, are these three operations sufficient? Might there be more things
      that a user wants to communicate to the executor, about how a function or task
      should be launched? For example, a priority or a hard real-time deadline.
    </p><p>
      The proposed library meets these needs by giving a function object or task
      an associated executor. As lightweight, copyable objects, executors allow us
      to encapsulate all sorts of additional information and behaviour on a fine-grained
      basis, such as priority. The associated executor determines how it should be
      executed, and the point of association may be distant in time and space from
      the point where a function is submitted using <code class="computeroutput"><span class="identifier">dispatch</span></code>,
      <code class="computeroutput"><span class="identifier">post</span></code> and <code class="computeroutput"><span class="identifier">defer</span></code>.
    </p></div><div class="section" title="10.&#160;Impact on the standard"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="executors.impact_on_the_standard"></a>10.&#160;Impact on the standard</h2></div></div></div><p>
      This is a pure library proposal. It does not add any new language features,
      nor does it alter any existing standard library headers. It makes additions
      to experimental headers that may also be modified by other Technical Specifications.
    </p><p>
      This library can be implemented using compilers that conform to the C++14 standard.
      An implementation of this library requires operating system-specific functions
      that lie outside the C++14 standard.
    </p></div><div class="section" title="11.&#160;Relationship to other proposals"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="executors.relationship_to_other_proposals"></a>11.&#160;Relationship to other proposals</h2></div></div></div><p>
      This proposal specifies the asynchronous model that underpins the P0112R0 Networking
      Library proposal. The proposed wording below is taken from the corresponding
      sections of P0112R0, but under a different namespace.
    </p></div><div class="section" title="12.&#160;Proposed text"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="executors.proposed_text"></a>12.&#160;Proposed text</h2></div></div></div><div class="toc"><dl><dt><span class="section"><a href="#executors.library_summary">12.1. Library summary</a></span></dt><dt><span class="section"><a href="#headers.executor">12.2. Header <code class="literal">&lt;experimental/executor&gt;</code> synopsis</a></span></dt><dt><span class="section"><a href="#executors.async_requirements">12.3. Requirements</a></span></dt><dd><dl><dt><span class="section"><a href="#requirements.proto_allocator">12.3.1. Proto-allocator requirements</a></span></dt><dt><span class="section"><a href="#requirements.execution_context">12.3.2. Execution context requirements</a></span></dt><dt><span class="section"><a href="#requirements.executor">12.3.3. Executor requirements</a></span></dt><dt><span class="section"><a href="#requirements.service">12.3.4. Service requirements</a></span></dt><dt><span class="section"><a href="#requirements.signature">12.3.5. Signature requirements</a></span></dt><dt><span class="section"><a href="#requirements.associator">12.3.6. Associator requirements</a></span></dt><dt><span class="section"><a href="#requirements.asynchronous_operations">12.3.7. Requirements on asynchronous operations</a></span></dt><dd><dl><dt><span class="section"><a href="#requirements.general_asynchronous_operation_concepts">12.3.7.1. General asynchronous operation concepts</a></span></dt><dt><span class="section"><a href="#requirements.completion_token">12.3.7.2. Completion tokens and handlers</a></span></dt><dt><span class="section"><a href="#requirements.automatic_deduction_of_initiating_function_return_type">12.3.7.3. Automatic deduction of initiating function return type</a></span></dt><dt><span class="section"><a href="#requirements.production_of_initiating_function_return_value">12.3.7.4. Production of initiating function return value</a></span></dt><dt><span class="section"><a href="#requirements.lifetime_of_initiating_function_arguments">12.3.7.5. Lifetime of initiating function arguments</a></span></dt><dt><span class="section"><a href="#requirements.non_blocking_requirements_on_initiating_functions">12.3.7.6. Non-blocking requirements on initiating functions</a></span></dt><dt><span class="section"><a href="#requirements.associated_executor">12.3.7.7. Associated executor</a></span></dt><dt><span class="section"><a href="#requirements.i_o_executor">12.3.7.8. I/O executor</a></span></dt><dt><span class="section"><a href="#requirements.completion_handler_executor">12.3.7.9. Completion handler executor</a></span></dt><dt><span class="section"><a href="#requirements.outstanding_work">12.3.7.10. Outstanding work</a></span></dt><dt><span class="section"><a href="#requirements.allocation_of_intermediate_storage">12.3.7.11. Allocation of intermediate storage</a></span></dt><dt><span class="section"><a href="#requirements.execution_of_completion_handler_on_completion_of_asynchronous_operation">12.3.7.12. Execution of completion handler on completion of asynchronous operation</a></span></dt><dt><span class="section"><a href="#requirements.completion_handlers_and_exceptions">12.3.7.13. Completion handlers and exceptions</a></span></dt></dl></dd></dl></dd><dt><span class="section"><a href="#classes.async_result">12.4. Class template <code class="literal">async_result</code></a></span></dt><dt><span class="section"><a href="#classes.async_completion">12.5. Class template <code class="literal">async_completion</code></a></span></dt><dt><span class="section"><a href="#classes.associated_allocator">12.6. Class template <code class="literal">associated_allocator</code></a></span></dt><dd><dl><dt><span class="section"><a href="#classes.__associated_allocator__members">12.6.1. <code class="literal">associated_allocator</code> members</a></span></dt></dl></dd><dt><span class="section"><a href="#functions.get_associated_allocator">12.7. Function <code class="literal">get_associated_allocator</code></a></span></dt><dt><span class="section"><a href="#classes.execution_context">12.8. Class <code class="literal">execution_context</code></a></span></dt><dd><dl><dt><span class="section"><a href="#classes.__execution_context__constructor">12.8.1. <code class="literal">execution_context</code> constructor</a></span></dt><dt><span class="section"><a href="#classes.__execution_context__destructor">12.8.2. <code class="literal">execution_context</code> destructor</a></span></dt><dt><span class="section"><a href="#classes.__execution_context__operations">12.8.3. <code class="literal">execution_context</code> operations</a></span></dt><dt><span class="section"><a href="#classes.__execution_context__protected_operations">12.8.4. <code class="literal">execution_context</code> protected operations</a></span></dt><dt><span class="section"><a href="#classes.__execution_context__globals">12.8.5. <code class="literal">execution_context</code> globals</a></span></dt></dl></dd><dt><span class="section"><a href="#classes.execution_context__service">12.9. Class <code class="literal">execution_context::service</code></a></span></dt><dt><span class="section"><a href="#classes.is_executor">12.10. Class template <code class="literal">is_executor</code></a></span></dt><dt><span class="section"><a href="#classes.executor_arg_t">12.11. Executor argument tag</a></span></dt><dt><span class="section"><a href="#classes.uses_executor">12.12. <code class="literal">uses_executor</code></a></span></dt><dd><dl><dt><span class="section"><a href="#classes.__uses_executor__trait">12.12.1. <code class="literal">uses_executor</code> trait</a></span></dt><dt><span class="section"><a href="#classes.uses_executor_construction">12.12.2. uses-executor construction</a></span></dt></dl></dd><dt><span class="section"><a href="#classes.associated_executor">12.13. Class template <code class="literal">associated_executor</code></a></span></dt><dd><dl><dt><span class="section"><a href="#classes.__associated_executor__members">12.13.1. <code class="literal">associated_executor</code> members</a></span></dt></dl></dd><dt><span class="section"><a href="#functions.get_associated_executor">12.14. Function <code class="literal">get_associated_executor</code></a></span></dt><dt><span class="section"><a href="#classes.executor_binder">12.15. Class template <code class="literal">executor_binder</code></a></span></dt><dd><dl><dt><span class="section"><a href="#classes.__executor_binder__constructors">12.15.1. <code class="literal">executor_binder</code> constructors</a></span></dt><dt><span class="section"><a href="#classes.__executor_binder__access">12.15.2. <code class="literal">executor_binder</code> access</a></span></dt><dt><span class="section"><a href="#classes.__executor_binder__invocation">12.15.3. <code class="literal">executor_binder</code> invocation</a></span></dt><dt><span class="section"><a href="#classes.class_template_partial_specialization___async_result_">12.15.4. Class template partial specialization <code class="literal">async_result</code></a></span></dt><dt><span class="section"><a href="#classes.class_template_partial_specialization___associated_allocator_">12.15.5. Class template partial specialization <code class="literal">associated_allocator</code></a></span></dt><dt><span class="section"><a href="#classes.class_template_partial_specialization___associated_executor_">12.15.6. Class template partial specialization <code class="literal">associated_executor</code></a></span></dt></dl></dd><dt><span class="section"><a href="#functions.bind_executor">12.16. Function <code class="literal">bind_executor</code></a></span></dt><dt><span class="section"><a href="#classes.executor_work_guard">12.17. Class template <code class="literal">executor_work_guard</code></a></span></dt><dd><dl><dt><span class="section"><a href="#classes.__executor_work_guard__members">12.17.1. <code class="literal">executor_work_guard</code> members</a></span></dt></dl></dd><dt><span class="section"><a href="#functions.make_work_guard">12.18. Function <code class="literal">make_work_guard</code></a></span></dt><dt><span class="section"><a href="#classes.system_executor">12.19. Class <code class="literal">system_executor</code></a></span></dt><dd><dl><dt><span class="section"><a href="#classes.__system_executor__operations">12.19.1. <code class="literal">system_executor</code> operations</a></span></dt><dt><span class="section"><a href="#classes.__system_executor__comparisons">12.19.2. <code class="literal">system_executor</code> comparisons</a></span></dt></dl></dd><dt><span class="section"><a href="#classes.system_context">12.20. Class <code class="literal">system_context</code></a></span></dt><dt><span class="section"><a href="#classes.bad_executor">12.21. Class <code class="literal">bad_executor</code></a></span></dt><dt><span class="section"><a href="#classes.executor">12.22. Class <code class="literal">executor</code></a></span></dt><dd><dl><dt><span class="section"><a href="#classes.__executor__constructors">12.22.1. <code class="literal">executor</code> constructors</a></span></dt><dt><span class="section"><a href="#classes.__executor__assignment">12.22.2. <code class="literal">executor</code> assignment</a></span></dt><dt><span class="section"><a href="#classes.__executor__destructor">12.22.3. <code class="literal">executor</code> destructor</a></span></dt><dt><span class="section"><a href="#classes.__executor__modifiers">12.22.4. <code class="literal">executor</code> modifiers</a></span></dt><dt><span class="section"><a href="#classes.__executor__operations">12.22.5. <code class="literal">executor</code> operations</a></span></dt><dt><span class="section"><a href="#classes.__executor__capacity">12.22.6. <code class="literal">executor</code> capacity</a></span></dt><dt><span class="section"><a href="#classes.__executor__target_access">12.22.7. <code class="literal">executor</code> target access</a></span></dt><dt><span class="section"><a href="#classes.__executor__comparisons">12.22.8. <code class="literal">executor</code> comparisons</a></span></dt><dt><span class="section"><a href="#classes.__executor__specialized_algorithms">12.22.9. <code class="literal">executor</code> specialized algorithms</a></span></dt></dl></dd><dt><span class="section"><a href="#functions.dispatch">12.23. Function <code class="literal">dispatch</code></a></span></dt><dt><span class="section"><a href="#functions.post">12.24. Function <code class="literal">post</code></a></span></dt><dt><span class="section"><a href="#functions.defer">12.25. Function <code class="literal">defer</code></a></span></dt><dt><span class="section"><a href="#classes.strand">12.26. Class template <code class="literal">strand</code></a></span></dt><dd><dl><dt><span class="section"><a href="#classes.__strand__constructors">12.26.1. <code class="literal">strand</code> constructors</a></span></dt><dt><span class="section"><a href="#classes.__strand__assignment">12.26.2. <code class="literal">strand</code> assignment</a></span></dt><dt><span class="section"><a href="#classes.__strand__destructor">12.26.3. <code class="literal">strand</code> destructor</a></span></dt><dt><span class="section"><a href="#classes.__strand__operations">12.26.4. <code class="literal">strand</code> operations</a></span></dt><dt><span class="section"><a href="#classes.__strand__comparisons">12.26.5. <code class="literal">strand</code> comparisons</a></span></dt></dl></dd><dt><span class="section"><a href="#classes.use_future_t">12.27. Class template <code class="literal">use_future_t</code></a></span></dt><dd><dl><dt><span class="section"><a href="#classes.__use_future_t__constructors">12.27.1. <code class="literal">use_future_t</code> constructors</a></span></dt><dt><span class="section"><a href="#classes.__use_future_t__members">12.27.2. <code class="literal">use_future_t</code> members</a></span></dt><dt><span class="section"><a href="#classes.use_future_t_result">12.27.3. Partial class template specialization <code class="literal">async_result</code>
        for <code class="literal">use_future_t</code></a></span></dt></dl></dd><dt><span class="section"><a href="#classes.async_result_packaged_task">12.28. Partial class template specialization <code class="literal">async_result</code>
      for <code class="literal">packaged_task</code></a></span></dt><dt><span class="section"><a href="#headers.thread_pool">12.29. Header <code class="literal">&lt;experimental/thread_pool&gt;</code> synopsis</a></span></dt><dt><span class="section"><a href="#classes.thread_pool">12.30. Class <code class="literal">thread_pool</code></a></span></dt><dd><dl><dt><span class="section"><a href="#classes.__thread_pool__members">12.30.1. <code class="literal">thread_pool</code> members</a></span></dt></dl></dd><dt><span class="section"><a href="#classes.thread_pool__executor_type">12.31. Class <code class="literal">thread_pool::executor_type</code></a></span></dt><dd><dl><dt><span class="section"><a href="#classes.__thread_pool__executor_type__constructors">12.31.1. <code class="literal">thread_pool::executor_type</code> constructors</a></span></dt><dt><span class="section"><a href="#classes.__thread_pool__executor_type__assignment">12.31.2. <code class="literal">thread_pool::executor_type</code> assignment</a></span></dt><dt><span class="section"><a href="#classes.__thread_pool__executor_type__operations">12.31.3. <code class="literal">thread_pool::executor_type</code> operations</a></span></dt><dt><span class="section"><a href="#classes.__thread_pool__executor_type__comparisons">12.31.4. <code class="literal">thread_pool::executor_type</code> comparisons</a></span></dt></dl></dd><dt><span class="section"><a href="#headers.loop_scheduler">12.32. Header <code class="literal">&lt;experimental/loop_scheduler&gt;</code> synopsis</a></span></dt><dt><span class="section"><a href="#classes.loop_scheduler">12.33. Class <code class="literal">loop_scheduler</code></a></span></dt><dd><dl><dt><span class="section"><a href="#classes.__loop_scheduler__members">12.33.1. <code class="literal">loop_scheduler</code> members</a></span></dt></dl></dd><dt><span class="section"><a href="#classes.loop_scheduler__executor_type">12.34. Class <code class="literal">loop_scheduler::executor_type</code></a></span></dt><dd><dl><dt><span class="section"><a href="#classes.__loop_scheduler__executor_type__constructors">12.34.1. <code class="literal">loop_scheduler::executor_type</code> constructors</a></span></dt><dt><span class="section"><a href="#classes.__loop_scheduler__executor_type__assignment">12.34.2. <code class="literal">loop_scheduler::executor_type</code> assignment</a></span></dt><dt><span class="section"><a href="#classes.__loop_scheduler__executor_type__operations">12.34.3. <code class="literal">loop_scheduler::executor_type</code> operations</a></span></dt><dt><span class="section"><a href="#classes.__loop_scheduler__executor_type__comparisons">12.34.4. <code class="literal">loop_scheduler::executor_type</code> comparisons</a></span></dt></dl></dd></dl></div><div class="section" title="12.1.&#160;Library summary"><div class="titlepage"><div><div><h3 class="title"><a name="executors.library_summary"></a>12.1.&#160;Library summary</h3></div></div></div><div class="table"><a name="executors.proposed_text.library_summary.t0"></a><p class="title"><b>Table&#160;1.&#160;Library summary</b></p><div class="table-contents"><table class="table" summary="Library summary"><colgroup><col><col></colgroup><thead><tr><th>
                <p>
                  Clause
                </p>
              </th><th>
                <p>
                  Header(s)
                </p>
              </th></tr></thead><tbody><tr><td>
                <p>
                  <a class="link" href="#headers.executor" title="12.2.&#160;Header &lt;experimental/executor&gt; synopsis">Asynchronous model</a>
                </p>
              </td><td>
                <p>
                  <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">experimental</span><span class="special">/</span><span class="identifier">executor</span><span class="special">&gt;</span></code>
                </p>
              </td></tr><tr><td>
                <p>
                  <a class="link" href="#headers.thread_pool" title="12.29.&#160;Header &lt;experimental/thread_pool&gt; synopsis">A fixed-size thread pool</a>
                </p>
              </td><td>
                <p>
                  <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">experimental</span><span class="special">/</span><span class="identifier">thread_pool</span><span class="special">&gt;</span></code>
                </p>
              </td></tr><tr><td>
                <p>
                  <a class="link" href="#headers.loop_scheduler" title="12.32.&#160;Header &lt;experimental/loop_scheduler&gt; synopsis">A thread pool where existing
                  threads are assigned to the pool</a>
                </p>
              </td><td>
                <p>
                  <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">experimental</span><span class="special">/</span><span class="identifier">loop_scheduler</span><span class="special">&gt;</span></code>
                </p>
              </td></tr></tbody></table></div></div><br class="table-break"><p>
        Throughout this Technical Specification, the names of the template parameters
        are used to express type requirements, as listed in the table below.
      </p><div class="table"><a name="executors.proposed_text.library_summary.t1"></a><p class="title"><b>Table&#160;2.&#160;Template parameters and type requirements</b></p><div class="table-contents"><table class="table" summary="Template parameters and type requirements"><colgroup><col><col></colgroup><thead><tr><th>
                <p>
                  template parameter name
                </p>
              </th><th>
                <p>
                  type requirements
                </p>
              </th></tr></thead><tbody><tr><td>
                <p>
                  <code class="computeroutput"><span class="identifier">Allocator</span></code>
                </p>
              </td><td>
                <p>
                  C++Std [allocator.requirements]
                </p>
              </td></tr><tr><td>
                <p>
                  <code class="computeroutput"><span class="identifier">Clock</span></code>
                </p>
              </td><td>
                <p>
                  C++Std [time.clock.req]
                </p>
              </td></tr><tr><td>
                <p>
                  <code class="computeroutput"><span class="identifier">CompletionToken</span></code>
                </p>
              </td><td>
                <p>
                  <a class="link" href="#requirements.completion_token" title="12.3.7.2.&#160;Completion tokens and handlers">completion token</a>
                </p>
              </td></tr><tr><td>
                <p>
                  <code class="computeroutput"><span class="identifier">ExecutionContext</span></code>
                </p>
              </td><td>
                <p>
                  <a class="link" href="#requirements.execution_context" title="12.3.2.&#160;Execution context requirements">execution context</a>
                </p>
              </td></tr><tr><td>
                <p>
                  <code class="computeroutput"><span class="identifier">Executor</span></code>
                </p>
              </td><td>
                <p>
                  <a class="link" href="#requirements.executor" title="12.3.3.&#160;Executor requirements">executor</a>
                </p>
              </td></tr><tr><td>
                <p>
                  <code class="computeroutput"><span class="identifier">ProtoAllocator</span></code>
                </p>
              </td><td>
                <p>
                  <a class="link" href="#requirements.proto_allocator" title="12.3.1.&#160;Proto-allocator requirements">proto-allocator</a>
                </p>
              </td></tr><tr><td>
                <p>
                  <code class="computeroutput"><span class="identifier">Service</span></code>
                </p>
              </td><td>
                <p>
                  <a class="link" href="#requirements.service" title="12.3.4.&#160;Service requirements">service</a>
                </p>
              </td></tr><tr><td>
                <p>
                  <code class="computeroutput"><span class="identifier">Signature</span></code>
                </p>
              </td><td>
                <p>
                  <a class="link" href="#requirements.signature" title="12.3.5.&#160;Signature requirements">signature</a>
                </p>
              </td></tr></tbody></table></div></div><br class="table-break"></div><div class="section" title="12.2.&#160;Header &lt;experimental/executor&gt; synopsis"><div class="titlepage"><div><div><h3 class="title"><a name="headers.executor"></a>12.2.&#160;Header <code class="literal">&lt;experimental/executor&gt;</code> synopsis</h3></div></div></div><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Signature</span><span class="special">,</span> <span class="keyword">class</span> <span class="special">=</span> <span class="keyword">void</span><span class="special">&gt;</span>
    <span class="keyword">class</span> <a class="link" href="#classes.async_result" title="12.4.&#160;Class template async_result">async_result</a><span class="special">;</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Signature</span><span class="special">&gt;</span>
    <span class="keyword">struct</span> <a class="link" href="#classes.async_completion" title="12.5.&#160;Class template async_completion">async_completion</a><span class="special">;</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span> <span class="special">=</span> <span class="identifier">allocator</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;&gt;</span>
    <span class="keyword">struct</span> <a class="link" href="#classes.associated_allocator" title="12.6.&#160;Class template associated_allocator">associated_allocator</a><span class="special">;</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span> <span class="special">=</span> <span class="identifier">allocator</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;&gt;</span>
    <span class="keyword">using</span> <span class="identifier">associated_allocator_t</span> <span class="special">=</span> <span class="keyword">typename</span> <span class="identifier">associated_allocator</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;::</span><span class="identifier">type</span><span class="special">;</span>

  // <a class="link" href="#functions.get_associated_allocator" title="12.7.&#160;Function get_associated_allocator">get_associated_allocator</a>:

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
    <span class="identifier">associated_allocator_t</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">get_associated_allocator</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">t</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
    <span class="identifier">associated_allocator_t</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
      <span class="identifier">get_associated_allocator</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>

  <span class="keyword">enum</span> <span class="keyword">class</span> <span class="identifier">fork_event</span> <span class="special">{</span>
    <span class="identifier">prepare</span><span class="special">,</span>
    <span class="identifier">parent</span><span class="special">,</span>
    <span class="identifier">child</span>
  <span class="special">};</span>

  <span class="keyword">class</span> <a class="link" href="#classes.execution_context" title="12.8.&#160;Class execution_context">execution_context</a><span class="special">;</span>

  <span class="keyword">class</span> <span class="identifier">service_already_exists</span><span class="special">;</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Service</span><span class="special">&gt;</span> <span class="identifier">Service</span><span class="special">&amp;</span> <span class="identifier">use_service</span><span class="special">(</span><span class="identifier">execution_context</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">);</span>
  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Service</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="identifier">Service</span><span class="special">&amp;</span>
    <span class="identifier">make_service</span><span class="special">(</span><span class="identifier">execution_context</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">,</span> <span class="identifier">Args</span><span class="special">&amp;&amp;...</span> <span class="identifier">args</span><span class="special">);</span>
  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Service</span><span class="special">&gt;</span> <span class="keyword">bool</span> <span class="identifier">has_service</span><span class="special">(</span><span class="identifier">execution_context</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">struct</span> <a class="link" href="#classes.is_executor" title="12.10.&#160;Class template is_executor">is_executor</a><span class="special">;</span>

  <span class="keyword">struct</span> <a class="link" href="#classes.executor_arg_t" title="12.11.&#160;Executor argument tag">executor_arg_t</a> <span class="special">{</span> <span class="special">};</span>
  <span class="keyword">constexpr</span> <span class="identifier">executor_arg_t</span> <span class="identifier">executor_arg</span> <span class="special">=</span> <span class="identifier">executor_arg_t</span><span class="special">();</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span> <span class="keyword">struct</span> <a class="link" href="#classes.uses_executor" title="12.12.&#160;uses_executor">uses_executor</a><span class="special">;</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Executor</span> <span class="special">=</span> <span class="identifier">system_executor</span><span class="special">&gt;</span>
    <span class="keyword">struct</span> <a class="link" href="#classes.associated_executor" title="12.13.&#160;Class template associated_executor">associated_executor</a><span class="special">;</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Executor</span> <span class="special">=</span> <span class="identifier">system_executor</span><span class="special">&gt;</span>
    <span class="keyword">using</span> <span class="identifier">associated_executor_t</span> <span class="special">=</span> <span class="keyword">typename</span> <span class="identifier">associated_executor</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">&gt;::</span><span class="identifier">type</span><span class="special">;</span>

  // <a class="link" href="#functions.get_associated_executor" title="12.14.&#160;Function get_associated_executor">get_associated_executor</a>:

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
    <span class="identifier">associated_executor_t</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">get_associated_executor</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">t</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
    <span class="identifier">associated_executor_t</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
      <span class="identifier">get_associated_executor</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">&amp;</span> <span class="identifier">ex</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ExecutionContext</span><span class="special">&gt;</span>
    <span class="identifier">associated_executor_t</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">ExecutionContext</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&gt;</span>
      <span class="identifier">get_associated_executor</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">t</span><span class="special">,</span> <span class="identifier">ExecutionContext</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
    <span class="keyword">class</span> <a class="link" href="#classes.executor_binder" title="12.15.&#160;Class template executor_binder">executor_binder</a><span class="special">;</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Signature</span><span class="special">&gt;</span>
    <span class="keyword">class</span> <span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">&gt;,</span> <span class="identifier">Signature</span><span class="special">&gt;;</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
    <span class="keyword">struct</span> <span class="identifier">associated_allocator</span><span class="special">&lt;</span><span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">&gt;,</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;;</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Executor1</span><span class="special">&gt;</span>
    <span class="keyword">struct</span> <span class="identifier">associated_executor</span><span class="special">&lt;</span><span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">&gt;,</span> <span class="identifier">Executor1</span><span class="special">&gt;;</span>

  // <a class="link" href="#functions.bind_executor" title="12.16.&#160;Function bind_executor">bind_executor</a>:

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
    <span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">decay_t</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;,</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
      <span class="identifier">bind_executor</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">&amp;</span> <span class="identifier">ex</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&amp;&amp;</span> <span class="identifier">t</span><span class="special">);</span>
  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ExecutionContext</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
    <span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">decay_t</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;,</span> <span class="keyword">typename</span> <span class="identifier">ExecutionContext</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&gt;</span>
      <span class="identifier">bind_executor</span><span class="special">(</span><span class="identifier">ExecutionContext</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&amp;&amp;</span> <span class="identifier">t</span><span class="special">);</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
    <span class="keyword">class</span> <a class="link" href="#classes.executor_work_guard" title="12.17.&#160;Class template executor_work_guard">executor_work_guard</a><span class="special">;</span>

  // <a class="link" href="#functions.make_work_guard" title="12.18.&#160;Function make_work_guard">make_work_guard</a>:

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
    <span class="identifier">executor_work_guard</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;</span>
      <span class="identifier">make_work_guard</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">&amp;</span> <span class="identifier">ex</span><span class="special">);</span>
  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ExecutionContext</span><span class="special">&gt;</span>
    <span class="identifier">executor_work_guard</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">ExecutionContext</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&gt;</span>
      <span class="identifier">make_work_guard</span><span class="special">(</span><span class="identifier">ExecutionContext</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">);</span>
  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
    <span class="identifier">executor_work_guard</span><span class="special">&lt;</span><span class="identifier">associated_executor_t</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&gt;</span>
      <span class="identifier">make_work_guard</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">t</span><span class="special">);</span>
  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span>
    <span class="keyword">auto</span> <span class="identifier">make_work_guard</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">t</span><span class="special">,</span> <span class="identifier">U</span><span class="special">&amp;&amp;</span> <span class="identifier">u</span><span class="special">)</span>
      <span class="special">-&gt;</span> <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">make_work_guard</span><span class="special">(</span><span class="identifier">get_associated_executor</span><span class="special">(</span><span class="identifier">t</span><span class="special">,</span> <span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;(</span><span class="identifier">u</span><span class="special">))));</span>

  <span class="keyword">class</span> <a class="link" href="#classes.system_executor" title="12.19.&#160;Class system_executor">system_executor</a><span class="special">;</span>
  <span class="keyword">class</span> <a class="link" href="#classes.system_context" title="12.20.&#160;Class system_context">system_context</a><span class="special">;</span>

  <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">system_executor</span><span class="special">&amp;,</span> <span class="keyword">const</span> <span class="identifier">system_executor</span><span class="special">&amp;);</span>
  <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="keyword">const</span> <span class="identifier">system_executor</span><span class="special">&amp;,</span> <span class="keyword">const</span> <span class="identifier">system_executor</span><span class="special">&amp;);</span>

  <span class="keyword">class</span> <a class="link" href="#classes.bad_executor" title="12.21.&#160;Class bad_executor">bad_executor</a><span class="special">;</span>

  <span class="keyword">class</span> <a class="link" href="#classes.executor" title="12.22.&#160;Class executor">executor</a><span class="special">;</span>

  <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">,</span> <span class="identifier">nullptr_t</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="identifier">nullptr_t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">,</span> <span class="identifier">nullptr_t</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="identifier">nullptr_t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>

  // <a class="link" href="#functions.dispatch" title="12.23.&#160;Function dispatch">dispatch</a>:

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
    <span class="emphasis"><em>DEDUCED</em></span> <span class="identifier">dispatch</span><span class="special">(</span><span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">);</span>
  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
    <span class="emphasis"><em>DEDUCED</em></span> <span class="identifier">dispatch</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">&amp;</span> <span class="identifier">ex</span><span class="special">,</span> <span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">);</span>
  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ExecutionContext</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
    <span class="emphasis"><em>DEDUCED</em></span> <span class="identifier">dispatch</span><span class="special">(</span><span class="identifier">ExecutionContext</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">,</span> <span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">);</span>

  // <a class="link" href="#functions.post" title="12.24.&#160;Function post">post</a>:

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
    <span class="emphasis"><em>DEDUCED</em></span> <span class="identifier">post</span><span class="special">(</span><span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">);</span>
  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
    <span class="emphasis"><em>DEDUCED</em></span> <span class="identifier">post</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">&amp;</span> <span class="identifier">ex</span><span class="special">,</span> <span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">);</span>
  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ExecutionContext</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
    <span class="emphasis"><em>DEDUCED</em></span> <span class="identifier">post</span><span class="special">(</span><span class="identifier">ExecutionContext</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">,</span> <span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">);</span>

  // <a class="link" href="#functions.defer" title="12.25.&#160;Function defer">defer</a>:

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
    <span class="emphasis"><em>DEDUCED</em></span> <span class="identifier">defer</span><span class="special">(</span><span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">);</span>
  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
    <span class="emphasis"><em>DEDUCED</em></span> <span class="identifier">defer</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">&amp;</span> <span class="identifier">ex</span><span class="special">,</span> <span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">);</span>
  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ExecutionContext</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
    <span class="emphasis"><em>DEDUCED</em></span> <span class="identifier">defer</span><span class="special">(</span><span class="identifier">ExecutionContext</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">,</span> <span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">);</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
    <span class="keyword">class</span> <a class="link" href="#classes.strand" title="12.26.&#160;Class template strand">strand</a><span class="special">;</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
    <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;&amp;</span> <span class="identifier">b</span><span class="special">);</span>
  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
    <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="keyword">const</span> <span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;&amp;</span> <span class="identifier">b</span><span class="special">);</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ProtoAllocator</span> <span class="special">=</span> <span class="identifier">allocator</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;&gt;</span>
    <span class="keyword">class</span> <a class="link" href="#classes.use_future_t" title="12.27.&#160;Class template use_future_t">use_future_t</a><span class="special">;</span>

  <span class="keyword">constexpr</span> <span class="identifier">use_future_t</span><span class="special">&lt;&gt;</span> <span class="identifier">use_future</span> <span class="special">=</span> <span class="identifier">use_future_t</span><span class="special">&lt;&gt;();</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Result</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span>
    <span class="keyword">class</span> <span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">use_future_t</span><span class="special">&lt;</span><span class="identifier">ProtoAllocator</span><span class="special">&gt;,</span> <span class="identifier">Result</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...)&gt;;</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">Args</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Signature</span><span class="special">&gt;</span>
    <span class="keyword">class</span> <a class="link" href="#classes.async_result_packaged_task" title="12.28.&#160;Partial class template specialization async_result for packaged_task">async_result&lt;packaged_task&lt;Result(Args...)&gt;, Signature&gt;</a><span class="special">;</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Allocator</span><span class="special">&gt;</span>
    <span class="keyword">struct</span> <span class="identifier">uses_allocator</span><span class="special">&lt;</span><span class="identifier">experimental</span><span class="special">::</span>concurrency_v2<span class="special">::</span><span class="identifier">executor</span><span class="special">,</span> <span class="identifier">Allocator</span><span class="special">&gt;</span>
      <span class="special">:</span> <span class="identifier">true_type</span> <span class="special">{};</span>

<span class="special">}</span> <span class="comment">// namespace std</span>
</pre></div><div class="section" title="12.3.&#160;Requirements"><div class="titlepage"><div><div><h3 class="title"><a name="executors.async_requirements"></a>12.3.&#160;Requirements</h3></div></div></div><div class="section" title="12.3.1.&#160;Proto-allocator requirements"><div class="titlepage"><div><div><h4 class="title"><a name="requirements.proto_allocator"></a>12.3.1.&#160;Proto-allocator requirements</h4></div></div></div><p>
          A type <code class="computeroutput"><span class="identifier">A</span></code> meets the proto-allocator
          requirements if <code class="computeroutput"><span class="identifier">A</span></code> is <code class="computeroutput"><span class="identifier">CopyConstructible</span></code> (C++Std [copyconstructible]),
          <code class="computeroutput"><span class="identifier">Destructible</span></code> (C++Std [destructible]),
          and <code class="computeroutput"><span class="identifier">allocator_traits</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">&gt;::</span><span class="identifier">rebind_alloc</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;</span></code>
          meets the allocator requirements (C++Std [allocator.requirements]), where
          <code class="computeroutput"><span class="identifier">U</span></code> is an object type. [<span class="emphasis"><em>Note:</em></span>
          For example, <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span></code>
          meets the proto-allocator requirements but not the allocator requirements.
          &#8212;<span class="emphasis"><em>end note</em></span>] No constructor, comparison operator, copy
          operation, move operation, or swap operation on these types shall exit
          via an exception.
        </p></div><div class="section" title="12.3.2.&#160;Execution context requirements"><div class="titlepage"><div><div><h4 class="title"><a name="requirements.execution_context"></a>12.3.2.&#160;Execution context requirements</h4></div></div></div><p>
          A type <code class="computeroutput"><span class="identifier">X</span></code> meets the <code class="computeroutput"><span class="identifier">ExecutionContext</span></code> requirements if it is
          publicly and unambiguously derived from <code class="computeroutput"><span class="identifier">execution_context</span></code>,
          and satisfies the additional requirements listed below.
        </p><p>
          In the table below, <code class="computeroutput"><span class="identifier">x</span></code> denotes
          a value of type <code class="computeroutput"><span class="identifier">X</span></code>.
        </p><div class="table"><a name="requirements.proposed_text.async_requirements.execution_context.t0"></a><p class="title"><b>Table&#160;3.&#160;ExecutionContext requirements</b></p><div class="table-contents"><table class="table" summary="ExecutionContext requirements"><colgroup><col><col><col></colgroup><thead><tr><th>
                  <p>
                    expression
                  </p>
                </th><th>
                  <p>
                    return type
                  </p>
                </th><th>
                  <p>
                    assertion/note<br> pre/post-condition
                  </p>
                </th></tr></thead><tbody><tr><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">X</span><span class="special">::</span><span class="identifier">executor_type</span></code>
                  </p>
                </td><td>
                  <p>
                    type meeting <a class="link" href="#requirements.executor" title="12.3.3.&#160;Executor requirements"><code class="computeroutput"><span class="identifier">Executor</span></code></a> requirements
                  </p>
                </td><td>
                </td></tr><tr><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">x</span><span class="special">.~</span><span class="identifier">X</span><span class="special">()</span></code>
                  </p>
                </td><td>
                </td><td>
                  <p>
                    Destroys all unexecuted function objects that were submitted
                    via an executor object that is associated with the execution
                    context.
                  </p>
                </td></tr><tr><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">x</span><span class="special">.</span><span class="identifier">get_executor</span><span class="special">()</span></code>
                  </p>
                </td><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">X</span><span class="special">::</span><span class="identifier">executor_type</span></code>
                  </p>
                </td><td>
                  <p>
                    Returns an executor object that is associated with the execution
                    context.
                  </p>
                </td></tr></tbody></table></div></div><br class="table-break"></div><div class="section" title="12.3.3.&#160;Executor requirements"><div class="titlepage"><div><div><h4 class="title"><a name="requirements.executor"></a>12.3.3.&#160;Executor requirements</h4></div></div></div><p>
          The library describes a standard set of requirements for <span class="emphasis"><em>executors</em></span>.
          A type meeting the <code class="computeroutput"><span class="identifier">Executor</span></code>
          requirements embodies a set of rules for determining how submitted function
          objects are to be executed.
        </p><p>
          A type <code class="computeroutput"><span class="identifier">X</span></code> meets the <code class="computeroutput"><span class="identifier">Executor</span></code> requirements if it satisfies
          the requirements of <code class="computeroutput"><span class="identifier">CopyConstructible</span></code>
          (C++Std [copyconstructible]) and <code class="computeroutput"><span class="identifier">Destructible</span></code>
          (C++Std [destructible]), as well as the additional requirements listed
          below.
        </p><p>
          No constructor, comparison operator, copy operation, move operation, swap
          operation, or member functions <code class="computeroutput"><span class="identifier">context</span></code>,
          <code class="computeroutput"><span class="identifier">on_work_started</span></code>, and <code class="computeroutput"><span class="identifier">on_work_finished</span></code> on these types shall
          exit via an exception.
        </p><p>
          The executor copy constructor, comparison operators, and other member functions
          defined in these requirements shall not introduce data races as a result
          of concurrent calls to those functions from different threads.
        </p><p>
          In the table below, <code class="computeroutput"><span class="identifier">x1</span></code>
          and <code class="computeroutput"><span class="identifier">x2</span></code> denote values of
          type <code class="computeroutput"><span class="identifier">X</span></code>, <code class="computeroutput"><span class="identifier">cx1</span></code>
          and <code class="computeroutput"><span class="identifier">cx2</span></code> denote (possibly
          const) values of type <code class="computeroutput"><span class="identifier">X</span></code>,
          <code class="computeroutput"><span class="identifier">mx1</span></code> denotes an xvalue of
          type <code class="computeroutput"><span class="identifier">X</span></code>, <code class="computeroutput"><span class="identifier">f</span></code>
          denotes a <code class="computeroutput"><span class="identifier">MoveConstructible</span></code>
          (C++Std [moveconstructible]) function object callable with zero arguments,
          <code class="computeroutput"><span class="identifier">a</span></code> denotes a (possibly const)
          value of type <code class="computeroutput"><span class="identifier">A</span></code> meeting
          the <code class="computeroutput"><span class="identifier">Allocator</span></code> requirements
          (C++Std [allocator.requirements]), and <code class="computeroutput"><span class="identifier">u</span></code>
          denotes an identifier.
        </p><div class="table"><a name="requirements.proposed_text.async_requirements.executor.t0"></a><p class="title"><b>Table&#160;4.&#160;Executor requirements</b></p><div class="table-contents"><table class="table" summary="Executor requirements"><colgroup><col><col><col></colgroup><thead><tr><th>
                  <p>
                    expression
                  </p>
                </th><th>
                  <p>
                    type
                  </p>
                </th><th>
                  <p>
                    assertion/note<br> pre/post-conditions
                  </p>
                </th></tr></thead><tbody><tr><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">X</span> <span class="identifier">u</span><span class="special">(</span><span class="identifier">cx1</span><span class="special">);</span></code>
                  </p>
                </td><td>
                </td><td>
                  <p>
                    Shall not exit via an exception.<br> <br> post: <code class="computeroutput"><span class="identifier">u</span> <span class="special">==</span>
                    <span class="identifier">cx1</span></code> and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">addressof</span><span class="special">(</span><span class="identifier">u</span><span class="special">.</span><span class="identifier">context</span><span class="special">())</span>
                    <span class="special">==</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">addressof</span><span class="special">(</span><span class="identifier">cx1</span><span class="special">.</span><span class="identifier">context</span><span class="special">()).</span></code>
                  </p>
                </td></tr><tr><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">X</span> <span class="identifier">u</span><span class="special">(</span><span class="identifier">mx1</span><span class="special">);</span></code>
                  </p>
                </td><td>
                </td><td>
                  <p>
                    Shall not exit via an exception.<br> <br> post: <code class="computeroutput"><span class="identifier">u</span></code> equals the prior value of
                    <code class="computeroutput"><span class="identifier">mx1</span></code> and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">addressof</span><span class="special">(</span><span class="identifier">u</span><span class="special">.</span><span class="identifier">context</span><span class="special">())</span></code>
                    equals the prior value of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">addressof</span><span class="special">(</span><span class="identifier">mx1</span><span class="special">.</span><span class="identifier">context</span><span class="special">())</span></code>.
                  </p>
                </td></tr><tr><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">cx1</span> <span class="special">==</span>
                    <span class="identifier">cx2</span></code>
                  </p>
                </td><td>
                  <p>
                    <code class="computeroutput"><span class="keyword">bool</span></code>
                  </p>
                </td><td>
                  <p>
                    Returns <code class="computeroutput"><span class="keyword">true</span></code> only
                    if <code class="computeroutput"><span class="identifier">cx1</span></code> and <code class="computeroutput"><span class="identifier">cx2</span></code> can be interchanged with
                    identical effects in any of the expressions defined in these
                    type requirements. [<span class="emphasis"><em>Note:</em></span> Returning <code class="computeroutput"><span class="keyword">false</span></code> does not necessarily imply
                    that the effects are not identical. &#8212;<span class="emphasis"><em>end note</em></span>]
                    <br> <br> <code class="computeroutput"><span class="keyword">operator</span><span class="special">==</span></code> shall be reflexive, symmetric,
                    and transitive, and shall not exit via an exception.
                  </p>
                </td></tr><tr><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">cx1</span> <span class="special">!=</span>
                    <span class="identifier">cx2</span></code>
                  </p>
                </td><td>
                  <p>
                    <code class="computeroutput"><span class="keyword">bool</span></code>
                  </p>
                </td><td>
                  <p>
                    Same as <code class="computeroutput"><span class="special">!(</span><span class="identifier">cx1</span>
                    <span class="special">==</span> <span class="identifier">cx2</span><span class="special">)</span></code>.
                  </p>
                </td></tr><tr><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">x1</span><span class="special">.</span><span class="identifier">context</span><span class="special">()</span></code>
                  </p>
                </td><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">execution_context</span><span class="special">&amp;</span></code>, or <code class="computeroutput"><span class="identifier">E</span><span class="special">&amp;</span></code> where <code class="computeroutput"><span class="identifier">E</span></code>
                    is a type that satifisfies the <a class="link" href="#requirements.execution_context" title="12.3.2.&#160;Execution context requirements"><code class="computeroutput"><span class="identifier">ExecutionContext</span></code></a> requirements.
                  </p>
                </td><td>
                  <p>
                    Shall not exit via an exception.<br> <br> The comparison
                    operators and member functions defined in these requirements
                    shall not alter the reference returned by this function.
                  </p>
                </td></tr><tr><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">x1</span><span class="special">.</span><span class="identifier">on_work_started</span><span class="special">()</span></code>
                  </p>
                </td><td>
                </td><td>
                  <p>
                    Shall not exit via an exception.
                  </p>
                </td></tr><tr><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">x1</span><span class="special">.</span><span class="identifier">on_work_finished</span><span class="special">()</span></code>
                  </p>
                </td><td>
                </td><td>
                  <p>
                    Shall not exit via an exception.<br> <br> Precondition: A
                    preceding call <code class="computeroutput"><span class="identifier">x2</span><span class="special">.</span><span class="identifier">on_work_started</span><span class="special">()</span></code> where <code class="computeroutput"><span class="identifier">x1</span>
                    <span class="special">==</span> <span class="identifier">x2</span></code>.
                  </p>
                </td></tr><tr><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">x1</span><span class="special">.</span><span class="identifier">dispatch</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">a</span><span class="special">)</span></code>
                  </p>
                </td><td>
                </td><td>
                  <p>
                    Effects: Creates an object <code class="computeroutput"><span class="identifier">f1</span></code>
                    initialized with <code class="literal"><span class="emphasis"><em>DECAY_COPY</em></span></code><code class="computeroutput"><span class="special">(</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Func</span><span class="special">&gt;(</span><span class="identifier">f</span><span class="special">))</span></code> (C++Std [thread.decaycopy])
                    in the current thread of execution . Calls <code class="computeroutput"><span class="identifier">f1</span><span class="special">()</span></code> at most once. The executor
                    may block forward progress of the caller until <code class="computeroutput"><span class="identifier">f1</span><span class="special">()</span></code>
                    finishes execution.<br> <br> Executor implementations should
                    use the supplied allocator to allocate any memory required to
                    store the function object. Prior to invoking the function object,
                    the executor shall deallocate any memory allocated. [<span class="emphasis"><em>Note:</em></span>
                    Executors defined in this Technical Specification always use
                    the supplied allocator unless otherwise specified. &#8212;<span class="emphasis"><em>end
                    note</em></span>] <br> <br> Synchronization: The invocation
                    of <code class="computeroutput"><span class="identifier">dispatch</span></code> synchronizes
                    with (C++Std [intro.multithread]) the invocation of <code class="computeroutput"><span class="identifier">f1</span></code>.
                  </p>
                </td></tr><tr><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">x1</span><span class="special">.</span><span class="identifier">post</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">a</span><span class="special">)</span></code><br>
                    <code class="computeroutput"><span class="identifier">x1</span><span class="special">.</span><span class="identifier">defer</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">a</span><span class="special">)</span></code>
                  </p>
                </td><td>
                </td><td>
                  <p>
                    Effects: Creates an object <code class="computeroutput"><span class="identifier">f1</span></code>
                    initialized with <code class="literal"><span class="emphasis"><em>DECAY_COPY</em></span></code><code class="computeroutput"><span class="special">(</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Func</span><span class="special">&gt;(</span><span class="identifier">f</span><span class="special">))</span></code> in the current thread of execution.
                    Calls <code class="computeroutput"><span class="identifier">f1</span><span class="special">()</span></code>
                    at most once. The executor shall not block forward progress of
                    the caller pending completion of <code class="computeroutput"><span class="identifier">f1</span><span class="special">()</span></code>.<br> <br> Executor implementations
                    should use the supplied allocator to allocate any memory required
                    to store the function object. Prior to invoking the function
                    object, the executor shall deallocate any memory allocated. [<span class="emphasis"><em>Note:</em></span>
                    Executors defined in this Technical Specification always use
                    the supplied allocator unless otherwise specified. &#8212;<span class="emphasis"><em>end
                    note</em></span>] <br> <br> Synchronization: The invocation
                    of <code class="computeroutput"><span class="identifier">post</span></code> or <code class="computeroutput"><span class="identifier">defer</span></code> synchronizes with (C++Std
                    [intro.multithread]) the invocation of <code class="computeroutput"><span class="identifier">f1</span></code>.<br>
                    <br> [<span class="emphasis"><em>Note:</em></span> Although the requirements
                    placed on <code class="computeroutput"><span class="identifier">defer</span></code>
                    are identical to <code class="computeroutput"><span class="identifier">post</span></code>,
                    the use of <code class="computeroutput"><span class="identifier">post</span></code>
                    conveys a preference that the caller <span class="emphasis"><em>does not</em></span>
                    block the first step of <code class="literal">f1</code>'s progress, whereas
                    <code class="computeroutput"><span class="identifier">defer</span></code> conveys
                    a preference that the caller <span class="emphasis"><em>does</em></span> block
                    the first step of <code class="literal">f1</code>. One use of <code class="computeroutput"><span class="identifier">defer</span></code> is to convey the intention
                    of the caller that <code class="literal">f1</code> is a continuation of
                    the current call context. The executor may use this information
                    to optimize or otherwise adjust the way in which <code class="computeroutput"><span class="identifier">f1</span></code> is invoked. &#8212;<span class="emphasis"><em>end
                    note</em></span>]
                  </p>
                </td></tr></tbody></table></div></div><br class="table-break"></div><div class="section" title="12.3.4.&#160;Service requirements"><div class="titlepage"><div><div><h4 class="title"><a name="requirements.service"></a>12.3.4.&#160;Service requirements</h4></div></div></div><p>
          A class is a <span class="emphasis"><em>service</em></span> if it is publicly and unambiguously
          derived from <code class="computeroutput"><span class="identifier">execution_context</span><span class="special">::</span><span class="identifier">service</span></code>,
          or if it is publicly and unambiguously derived from another service. For
          a service <code class="computeroutput"><span class="identifier">S</span></code>, <code class="computeroutput"><span class="identifier">S</span><span class="special">::</span><span class="identifier">key_type</span></code>
          shall be valid and denote a type (C++Std [temp.deduct]), <code class="computeroutput"><span class="identifier">is_base_of_v</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">S</span><span class="special">::</span><span class="identifier">key_type</span><span class="special">,</span> <span class="identifier">S</span><span class="special">&gt;</span></code>
          shall be <code class="computeroutput"><span class="keyword">true</span></code>, and <code class="computeroutput"><span class="identifier">S</span></code> shall satisfy the <code class="computeroutput"><span class="identifier">Destructible</span></code>
          requirements (C++Std [destructible]).
        </p><p>
          The first parameter of all service constructors shall be an lvalue reference
          to <code class="computeroutput"><span class="identifier">execution_context</span></code>. This
          parameter denotes the <code class="computeroutput"><span class="identifier">execution_context</span></code>
          object that represents a set of services, of which the service object will
          be a member. [<span class="emphasis"><em>Note:</em></span> These constructors may be called
          by the <code class="computeroutput"><span class="identifier">make_service</span></code> function.
          &#8212;<span class="emphasis"><em>end note</em></span>]
        </p><p>
          A service shall provide an explicit constructor with a single parameter
          of lvalue reference to <code class="computeroutput"><span class="identifier">execution_context</span></code>.
          [<span class="emphasis"><em>Note:</em></span> This constructor may be called by the <code class="computeroutput"><span class="identifier">use_service</span></code> function. &#8212;<span class="emphasis"><em>end note</em></span>]
        </p><p>
          [<span class="emphasis"><em>Example:</em></span> <br>
        </p><p>
</p><pre class="programlisting"><span class="keyword">class</span> <span class="identifier">my_service</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">execution_context</span><span class="special">::</span><span class="identifier">service</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
  <span class="keyword">typedef</span> <span class="identifier">my_service</span> <span class="identifier">key_type</span><span class="special">;</span>
  <span class="keyword">explicit</span> <span class="identifier">my_service</span><span class="special">(</span><span class="identifier">execution_context</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">);</span>
  <span class="identifier">my_service</span><span class="special">(</span><span class="identifier">execution_context</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">some_value</span><span class="special">);</span>
<span class="keyword">private</span><span class="special">:</span>
  <span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">shutdown</span><span class="special">()</span> <span class="keyword">noexcept</span> <span class="identifier">override</span><span class="special">;</span>
  ...
<span class="special">};</span>
</pre><p>
        </p><p>
          &#8212;<span class="emphasis"><em>end example</em></span>]
        </p><p>
          A service's <code class="computeroutput"><span class="identifier">shutdown</span></code> member
          function shall destroy all copies of user-defined function objects that
          are held by the service.
        </p></div><div class="section" title="12.3.5.&#160;Signature requirements"><div class="titlepage"><div><div><h4 class="title"><a name="requirements.signature"></a>12.3.5.&#160;Signature requirements</h4></div></div></div><p>
          A type satisfies the signature requirements if it is a call signature (C++Std
          [func.def]).
        </p></div><div class="section" title="12.3.6.&#160;Associator requirements"><div class="titlepage"><div><div><h4 class="title"><a name="requirements.associator"></a>12.3.6.&#160;Associator requirements</h4></div></div></div><p>
          An <span class="emphasis"><em>associator</em></span> defines a relationship between different
          types and objects where, given:
        </p><p>
          &#8212; a source object <code class="computeroutput"><span class="identifier">s</span></code> of type
          <code class="computeroutput"><span class="identifier">S</span></code>,
        </p><p>
          &#8212; type requirements <code class="computeroutput"><span class="identifier">R</span></code>, and
        </p><p>
          &#8212; a candidate object <code class="computeroutput"><span class="identifier">c</span></code> of
          type <code class="computeroutput"><span class="identifier">C</span></code> meeting the type
          requirements <code class="computeroutput"><span class="identifier">R</span></code>
        </p><p>
          an <span class="emphasis"><em>associated type</em></span> <code class="computeroutput"><span class="identifier">A</span></code>
          meeting the type requirements <code class="computeroutput"><span class="identifier">R</span></code>
          may be computed, and an <span class="emphasis"><em>associated object</em></span> <code class="computeroutput"><span class="identifier">a</span></code> of type <code class="computeroutput"><span class="identifier">A</span></code>
          may be obtained.
        </p><p>
          An associator shall be a class template that takes two template type arguments.
          The first template argument is the source type <code class="computeroutput"><span class="identifier">S</span></code>.
          The second template argument is the candidate type <code class="computeroutput"><span class="identifier">C</span></code>.
          The second template argument shall be defaulted to some default candidate
          type <code class="computeroutput"><span class="identifier">D</span></code> that satisfies the
          type requirements <code class="computeroutput"><span class="identifier">R</span></code>.
        </p><p>
          An associator shall additionally satisfy the requirements in the table
          below. In this table, <code class="computeroutput"><span class="identifier">X</span></code>
          is a class template that meets the associator requirements, <code class="computeroutput"><span class="identifier">S</span></code> is the source type, <code class="computeroutput"><span class="identifier">s</span></code>
          is a (possibly const) value of type <code class="computeroutput"><span class="identifier">S</span></code>,
          <code class="computeroutput"><span class="identifier">C</span></code> is the candidate type,
          <code class="computeroutput"><span class="identifier">c</span></code> is a (possibly const)
          value of type <code class="computeroutput"><span class="identifier">C</span></code>, <code class="computeroutput"><span class="identifier">D</span></code> is the default candidate type, and
          <code class="computeroutput"><span class="identifier">d</span></code> is a (possibly const)
          value of type <code class="computeroutput"><span class="identifier">D</span></code> that is
          the default candidate object.
        </p><div class="table"><a name="requirements.proposed_text.async_requirements.associator.t0"></a><p class="title"><b>Table&#160;5.&#160;Associator requirements</b></p><div class="table-contents"><table class="table" summary="Associator requirements"><colgroup><col><col><col></colgroup><thead><tr><th>
                  <p>
                    expression
                  </p>
                </th><th>
                  <p>
                    return type
                  </p>
                </th><th>
                  <p>
                    assertion/note<br> pre/post-conditions
                  </p>
                </th></tr></thead><tbody><tr><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">X</span><span class="special">&lt;</span><span class="identifier">S</span><span class="special">&gt;::</span><span class="identifier">type</span></code>
                  </p>
                </td><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">X</span><span class="special">&lt;</span><span class="identifier">S</span><span class="special">,</span>
                    <span class="identifier">D</span><span class="special">&gt;::</span><span class="identifier">type</span></code>
                  </p>
                </td><td>
                </td></tr><tr><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">X</span><span class="special">&lt;</span><span class="identifier">S</span><span class="special">,</span>
                    <span class="identifier">C</span><span class="special">&gt;::</span><span class="identifier">type</span></code>
                  </p>
                </td><td>
                </td><td>
                  <p>
                    The associated type.
                  </p>
                </td></tr><tr><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">X</span><span class="special">&lt;</span><span class="identifier">S</span><span class="special">&gt;::</span><span class="identifier">get</span><span class="special">(</span><span class="identifier">s</span><span class="special">)</span></code>
                  </p>
                </td><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">X</span><span class="special">&lt;</span><span class="identifier">S</span><span class="special">&gt;::</span><span class="identifier">type</span></code>
                  </p>
                </td><td>
                  <p>
                    Returns <code class="computeroutput"><span class="identifier">X</span><span class="special">&lt;</span><span class="identifier">S</span><span class="special">&gt;::</span><span class="identifier">get</span><span class="special">(</span><span class="identifier">S</span><span class="special">,</span>
                    <span class="identifier">d</span><span class="special">)</span></code>.
                  </p>
                </td></tr><tr><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">X</span><span class="special">&lt;</span><span class="identifier">S</span><span class="special">,</span>
                    <span class="identifier">C</span><span class="special">&gt;::</span><span class="identifier">get</span><span class="special">(</span><span class="identifier">s</span><span class="special">,</span>
                    <span class="identifier">c</span><span class="special">)</span></code>
                  </p>
                </td><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">X</span><span class="special">&lt;</span><span class="identifier">S</span><span class="special">,</span>
                    <span class="identifier">C</span><span class="special">&gt;::</span><span class="identifier">type</span></code>
                  </p>
                </td><td>
                  <p>
                    Returns the associated object.
                  </p>
                </td></tr></tbody></table></div></div><br class="table-break"><p>
          The associator's primary template shall be defined. A program may partially
          specialize the associator class template for some user-defined type <code class="computeroutput"><span class="identifier">S</span></code>.
        </p><p>
          Finally, the associator shall provide the following type alias and function
          template in the enclosing namespace:
        </p><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">S</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">C</span> <span class="special">=</span> <span class="identifier">D</span><span class="special">&gt;</span> <span class="keyword">using</span> <span class="emphasis"><em>X</em></span><span class="identifier">_t</span> <span class="special">=</span> <span class="keyword">typename</span> <span class="identifier">X</span><span class="special">&lt;</span><span class="identifier">S</span><span class="special">,</span> <span class="identifier">C</span><span class="special">&gt;::</span><span class="identifier">type</span><span class="special">;</span>

<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">S</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">C</span> <span class="special">=</span> <span class="identifier">D</span><span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">X</span><span class="special">&lt;</span><span class="identifier">S</span><span class="special">,</span> <span class="identifier">C</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">get_</span><span class="emphasis"><em>X</em></span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">S</span><span class="special">&amp;</span> <span class="identifier">s</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">C</span><span class="special">&amp;</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">d</span><span class="special">)</span>
<span class="special">{</span>
  <span class="keyword">return</span> <span class="identifier">X</span><span class="special">&lt;</span><span class="identifier">S</span><span class="special">,</span> <span class="identifier">C</span><span class="special">&gt;::</span><span class="identifier">get</span><span class="special">(</span><span class="identifier">s</span><span class="special">,</span> <span class="identifier">c</span><span class="special">);</span>
<span class="special">}</span>
</pre><p>
          where <code class="literal"><span class="emphasis"><em>X</em></span></code> is replaced with the name
          of the associator class template. [<span class="emphasis"><em>Note:</em></span> This function
          template is provided as a convenience, to automatically deduce the source
          and candidate types. &#8212;<span class="emphasis"><em>end note</em></span>]
        </p></div><div class="section" title="12.3.7.&#160;Requirements on asynchronous operations"><div class="titlepage"><div><div><h4 class="title"><a name="requirements.asynchronous_operations"></a>12.3.7.&#160;Requirements on asynchronous operations</h4></div></div></div><p>
          This section uses the names <code class="computeroutput"><span class="identifier">Alloc1</span></code>,
          <code class="computeroutput"><span class="identifier">Alloc2</span></code>, <code class="computeroutput"><span class="identifier">alloc1</span></code>,
          <code class="computeroutput"><span class="identifier">alloc2</span></code>, <code class="computeroutput"><span class="identifier">Args</span></code>,
          <code class="computeroutput"><span class="identifier">CompletionHandler</span></code>, <code class="computeroutput"><span class="identifier">completion_handler</span></code>, <code class="computeroutput"><span class="identifier">Executor1</span></code>,
          <code class="computeroutput"><span class="identifier">Executor2</span></code>, <code class="computeroutput"><span class="identifier">ex1</span></code>, <code class="computeroutput"><span class="identifier">ex2</span></code>,
          <code class="computeroutput"><span class="identifier">f</span></code>, <code class="literal"><span class="emphasis"><em>i</em></span></code>,
          <code class="literal"><span class="emphasis"><em>N</em></span></code>, <code class="computeroutput"><span class="identifier">Signature</span></code>,
          <code class="computeroutput"><span class="identifier">token</span></code>, <code class="literal">T<sub><span class="emphasis"><em>i</em></span></sub></code>,
          <code class="literal">t<sub><span class="emphasis"><em>i</em></span></sub></code>, <code class="computeroutput"><span class="identifier">work1</span></code>,
          and <code class="computeroutput"><span class="identifier">work2</span></code> as placeholders
          for specifying the requirements below.
        </p><div class="section" title="12.3.7.1.&#160;General asynchronous operation concepts"><div class="titlepage"><div><div><h5 class="title"><a name="requirements.general_asynchronous_operation_concepts"></a>12.3.7.1.&#160;General asynchronous operation concepts</h5></div></div></div><p>
            An <span class="emphasis"><em>initiating function</em></span> is a function which may be
            called to start an asynchronous operation. A <span class="emphasis"><em>completion handler</em></span>
            is a function object that will be invoked, at most once, with the result
            of the asynchronous operation.
          </p><p>
            The lifecycle of an asynchronous operation is comprised of the following
            events and phases:
          </p><p>
            &#8212; Event 1: The asynchronous operation is started by a call to the <span class="emphasis"><em>initiating
            function</em></span>.
          </p><p>
            &#8212; Phase 1: The asynchronous operation is now <span class="emphasis"><em>outstanding</em></span>.
          </p><p>
            &#8212; Event 2: The externally observable side effects of the asynchronous operation,
            if any, are fully established. The <span class="emphasis"><em>completion handler</em></span>
            is submitted to an executor.
          </p><p>
            &#8212; Phase 2: The asynchronous operation is now <span class="emphasis"><em>completed</em></span>.
          </p><p>
            &#8212; Event 3: The completion handler is called with the result of the asynchronous
            operation.
          </p><p>
            In this Technical Specification, all functions with the prefix <code class="computeroutput"><span class="identifier">async_</span></code> are initiating functions.
          </p></div><div class="section" title="12.3.7.2.&#160;Completion tokens and handlers"><div class="titlepage"><div><div><h5 class="title"><a name="requirements.completion_token"></a>12.3.7.2.&#160;Completion tokens and handlers</h5></div></div></div><p>
            Initiating functions:
          </p><p>
            &#8212; are function templates with template parameter <code class="computeroutput"><span class="identifier">CompletionToken</span></code>;
          </p><p>
            &#8212; accept, as the final parameter, a <span class="emphasis"><em>completion token</em></span>
            object <code class="computeroutput"><span class="identifier">token</span></code> of type
            <code class="computeroutput"><span class="identifier">CompletionToken</span></code>;
          </p><p>
            &#8212; specify a <span class="emphasis"><em>completion signature</em></span>, which is a call
            signature (C++Std [func.def]) <code class="computeroutput"><span class="identifier">Signature</span></code>
            that determines the arguments to the completion handler.
          </p><p>
            An initiating function determines the type <code class="computeroutput"><span class="identifier">CompletionHandler</span></code>
            of its completion handler function object by performing <code class="computeroutput"><span class="keyword">typename</span> <span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">decay_t</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;,</span> <span class="identifier">Signature</span><span class="special">&gt;::</span><span class="identifier">completion_handler_type</span></code>.
            The completion handler object <code class="computeroutput"><span class="identifier">completion_handler</span></code>
            is initialized with <code class="computeroutput"><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;(</span><span class="identifier">token</span><span class="special">)</span></code>. [<span class="emphasis"><em>Note:</em></span> No other
            requirements are placed on the type <code class="computeroutput"><span class="identifier">CompletionToken</span></code>.
            &#8212;<span class="emphasis"><em>end note</em></span>]
          </p><p>
            The type <code class="computeroutput"><span class="identifier">CompletionHandler</span></code>
            must satisfy the requirements of <code class="computeroutput"><span class="identifier">Destructible</span></code>
            (C++Std [destructible]) and <code class="computeroutput"><span class="identifier">MoveConstructible</span></code>
            (C++Std [moveconstructible]), and be callable with the specified call
            signature.
          </p><p>
            In this Technical Specification, all initiating functions specify a
            <span class="emphasis"><em>Completion signature</em></span> element that defines the call
            signature <code class="computeroutput"><span class="identifier">Signature</span></code>.
            The <span class="emphasis"><em>Completion signature</em></span> elements in this Technical
            Specification have named parameters, and the results of an asynchronous
            operation are specified in terms of these names.
          </p></div><div class="section" title="12.3.7.3.&#160;Automatic deduction of initiating function return type"><div class="titlepage"><div><div><h5 class="title"><a name="requirements.automatic_deduction_of_initiating_function_return_type"></a>12.3.7.3.&#160;Automatic deduction of initiating function return type</h5></div></div></div><p>
            The return type of an initiating function is <code class="computeroutput"><span class="keyword">typename</span>
            <span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">decay_t</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;,</span>
            <span class="identifier">Signature</span><span class="special">&gt;::</span><span class="identifier">return_type</span></code>.
          </p><p>
            For the sake of exposition, this Technical Specification sometimes annotates
            functions with a return type <code class="computeroutput"><span class="emphasis"><em>DEDUCED</em></span></code>. For every function declaration
            that returns <code class="computeroutput"><span class="emphasis"><em>DEDUCED</em></span></code>, the meaning is equivalent to specifying the
            return type as <code class="computeroutput"><span class="keyword">typename</span> <span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">decay_t</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;,</span>
            <span class="identifier">Signature</span><span class="special">&gt;::</span><span class="identifier">return_type</span></code>.
          </p></div><div class="section" title="12.3.7.4.&#160;Production of initiating function return value"><div class="titlepage"><div><div><h5 class="title"><a name="requirements.production_of_initiating_function_return_value"></a>12.3.7.4.&#160;Production of initiating function return value</h5></div></div></div><p>
            An initiating function produces its return type as follows:
          </p><p>
            &#8212; constructing an object <code class="computeroutput"><span class="identifier">result</span></code>
            of type <code class="computeroutput"><span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">decay_t</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;,</span> <span class="identifier">Signature</span><span class="special">&gt;</span></code>, initialized as <code class="computeroutput"><span class="identifier">result</span><span class="special">(</span><span class="identifier">completion_handler</span><span class="special">)</span></code>; and
          </p><p>
            &#8212; using <code class="computeroutput"><span class="identifier">result</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span></code>
            as the operand of the return statement.
          </p><p>
            [<span class="emphasis"><em>Example:</em></span> Given an asynchronous operation with
            <span class="emphasis"><em>Completion signature</em></span> <code class="computeroutput"><span class="keyword">void</span><span class="special">(</span><span class="identifier">R1</span> <span class="identifier">r1</span><span class="special">,</span> <span class="identifier">R2</span> <span class="identifier">r2</span><span class="special">)</span></code>, an initiating function meeting these
            requirements may be implemented as follows:
          </p><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
<span class="keyword">auto</span> <span class="identifier">async_xyz</span><span class="special">(</span><span class="identifier">T1</span> <span class="identifier">t1</span><span class="special">,</span> <span class="identifier">T2</span> <span class="identifier">t2</span><span class="special">,</span> <span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">)</span>
<span class="special">{</span>
  <span class="keyword">typename</span> <span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">decay_t</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;,</span> <span class="keyword">void</span><span class="special">(</span><span class="identifier">R1</span><span class="special">,</span> <span class="identifier">R2</span><span class="special">)&gt;::</span><span class="identifier">completion_handler_type</span>
    <span class="identifier">completion_handler</span><span class="special">(</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;(</span><span class="identifier">token</span><span class="special">));</span>

  <span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">decay_t</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;,</span> <span class="keyword">void</span><span class="special">(</span><span class="identifier">R1</span><span class="special">,</span> <span class="identifier">R2</span><span class="special">)&gt;</span> <span class="identifier">result</span><span class="special">(</span><span class="identifier">completion_handler</span><span class="special">);</span>

  <span class="comment">// initiate the operation and cause completion_handler to be invoked with</span>
  <span class="comment">// the result</span>

  <span class="keyword">return</span> <span class="identifier">result</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span>
<span class="special">}</span>
</pre><p>
            For convenience, initiating functions may be implemented using the <code class="computeroutput"><span class="identifier">async_completion</span></code> template:
          </p><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
<span class="keyword">auto</span> <span class="identifier">async_xyz</span><span class="special">(</span><span class="identifier">T1</span> <span class="identifier">t1</span><span class="special">,</span> <span class="identifier">T2</span> <span class="identifier">t2</span><span class="special">,</span> <span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">)</span>
<span class="special">{</span>
  <span class="identifier">async_completion</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">,</span> <span class="keyword">void</span><span class="special">(</span><span class="identifier">R1</span><span class="special">,</span> <span class="identifier">R2</span><span class="special">)&gt;</span> <span class="identifier">init</span><span class="special">(</span><span class="identifier">token</span><span class="special">);</span>

  <span class="comment">// initiate the operation and cause init.completion_handler to be invoked</span>
  <span class="comment">// with the result</span>

  <span class="keyword">return</span> <span class="identifier">init</span><span class="special">.</span><span class="identifier">result</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span>
<span class="special">}</span>
</pre><p>
            &#8212;<span class="emphasis"><em>end example</em></span>]
          </p></div><div class="section" title="12.3.7.5.&#160;Lifetime of initiating function arguments"><div class="titlepage"><div><div><h5 class="title"><a name="requirements.lifetime_of_initiating_function_arguments"></a>12.3.7.5.&#160;Lifetime of initiating function arguments</h5></div></div></div><p>
            Unless otherwise specified, the lifetime of arguments to initiating functions
            shall be treated as follows:
          </p><p>
            &#8212; If the parameter has a pointer type or has a type of lvalue reference
            to non-const, the implementation may assume the validity of the pointee
            or referent, respectively, until the completion handler is invoked. [<span class="emphasis"><em>Note:</em></span>
            In other words, the program must guarantee the validity of the argument
            until the completion handler is invoked. &#8212;<span class="emphasis"><em>end note</em></span>]
          </p><p>
            &#8212; Otherwise, the implementation must not assume the validity of the argument
            after the initiating function completes. [<span class="emphasis"><em>Note:</em></span>
            In other words, the program is not required to guarantee the validity
            of the argument after the initiating function completes. &#8212;<span class="emphasis"><em>end
            note</em></span>] The implementation may make copies of the argument,
            and all copies shall be destroyed no later than immediately after invocation
            of the completion handler.
          </p></div><div class="section" title="12.3.7.6.&#160;Non-blocking requirements on initiating functions"><div class="titlepage"><div><div><h5 class="title"><a name="requirements.non_blocking_requirements_on_initiating_functions"></a>12.3.7.6.&#160;Non-blocking requirements on initiating functions</h5></div></div></div><p>
            An initiating function shall not block (C++Std [defns.block]) the calling
            thread pending completion of the outstanding operation.
          </p><p>
            [<span class="emphasis"><em>Note:</em></span> Initiating functions may still block the
            calling thread for other reasons. For example, an initiating function
            may lock a mutex in order to synchronize access to shared data. &#8212;<span class="emphasis"><em>end
            note</em></span>]
          </p></div><div class="section" title="12.3.7.7.&#160;Associated executor"><div class="titlepage"><div><div><h5 class="title"><a name="requirements.associated_executor"></a>12.3.7.7.&#160;Associated executor</h5></div></div></div><p>
            Certain objects that participate in asynchronous operations have an
            <span class="emphasis"><em>associated executor</em></span>. These are obtained as specified
            below.
          </p></div><div class="section" title="12.3.7.8.&#160;I/O executor"><div class="titlepage"><div><div><h5 class="title"><a name="requirements.i_o_executor"></a>12.3.7.8.&#160;I/O executor</h5></div></div></div><p>
            An asynchronous operation has an associated executor satisfying the
            <a class="link" href="#requirements.executor" title="12.3.3.&#160;Executor requirements"><code class="computeroutput"><span class="identifier">Executor</span></code></a>
            requirements. If not otherwise specified by the asynchronous operation,
            this associated executor is an object of type <code class="computeroutput"><span class="identifier">system_executor</span></code>.
          </p><p>
            All asynchronous operations in this Technical Specification have an associated
            executor object that is determined as follows:
          </p><p>
            &#8212; If the initiating function is a member function, the associated executor
            is that returned by the <code class="computeroutput"><span class="identifier">get_executor</span></code>
            member function on the same object.
          </p><p>
            &#8212; If the initiating function is not a member function, the associated executor
            is that returned by the <code class="computeroutput"><span class="identifier">get_executor</span></code>
            member function of the first argument to the initiating function.
          </p><p>
            Let <code class="computeroutput"><span class="identifier">Executor1</span></code> be the
            type of the associated executor. Let <code class="computeroutput"><span class="identifier">ex1</span></code>
            be a value of type <code class="computeroutput"><span class="identifier">Executor1</span></code>,
            representing the associated executor object obtained as described above.
          </p></div><div class="section" title="12.3.7.9.&#160;Completion handler executor"><div class="titlepage"><div><div><h5 class="title"><a name="requirements.completion_handler_executor"></a>12.3.7.9.&#160;Completion handler executor</h5></div></div></div><p>
            A completion handler object of type <code class="computeroutput"><span class="identifier">CompletionHandler</span></code>
            has an associated executor of type <code class="computeroutput"><span class="identifier">Executor2</span></code>
            satisfying the <a class="link" href="#requirements.executor" title="12.3.3.&#160;Executor requirements">Executor requirements</a>.
            The type <code class="computeroutput"><span class="identifier">Executor2</span></code> is
            <code class="computeroutput"><span class="identifier">associated_executor_t</span><span class="special">&lt;</span><span class="identifier">CompletionHandler</span><span class="special">,</span> <span class="identifier">Executor1</span><span class="special">&gt;</span></code>. Let <code class="computeroutput"><span class="identifier">ex2</span></code>
            be a value of type <code class="computeroutput"><span class="identifier">Executor2</span></code>
            obtained by performing <code class="computeroutput"><span class="identifier">get_associated_executor</span><span class="special">(</span><span class="identifier">completion_handler</span><span class="special">,</span> <span class="identifier">ex1</span><span class="special">)</span></code>.
          </p></div><div class="section" title="12.3.7.10.&#160;Outstanding work"><div class="titlepage"><div><div><h5 class="title"><a name="requirements.outstanding_work"></a>12.3.7.10.&#160;Outstanding work</h5></div></div></div><p>
            The implementation of an asynchronous operation shall maintain an object
            <code class="computeroutput"><span class="identifier">work1</span></code> of type <code class="computeroutput"><span class="identifier">executor_work_guard</span><span class="special">&lt;</span><span class="identifier">Executor1</span><span class="special">&gt;</span></code>,
            initialized with <code class="computeroutput"><span class="identifier">work1</span><span class="special">(</span><span class="identifier">ex1</span><span class="special">)</span></code> and with <code class="computeroutput"><span class="identifier">work1</span><span class="special">.</span><span class="identifier">owns_work</span><span class="special">()</span> <span class="special">==</span> <span class="keyword">true</span></code>, until the asynchronous operation
            has completed.
          </p><p>
            The implementation of an asynchronous operation shall maintain an object
            <code class="computeroutput"><span class="identifier">work2</span></code> of type <code class="computeroutput"><span class="identifier">executor_work_guard</span><span class="special">&lt;</span><span class="identifier">Executor2</span><span class="special">&gt;</span></code>,
            initialized with <code class="computeroutput"><span class="identifier">work2</span><span class="special">(</span><span class="identifier">ex2</span><span class="special">)</span></code> and with <code class="computeroutput"><span class="identifier">work2</span><span class="special">.</span><span class="identifier">owns_work</span><span class="special">()</span> <span class="special">==</span> <span class="keyword">true</span></code>, until the asynchronous operation
            has completed and <code class="computeroutput"><span class="identifier">completion_handler</span></code>
            has been submitted for execution.
          </p></div><div class="section" title="12.3.7.11.&#160;Allocation of intermediate storage"><div class="titlepage"><div><div><h5 class="title"><a name="requirements.allocation_of_intermediate_storage"></a>12.3.7.11.&#160;Allocation of intermediate storage</h5></div></div></div><p>
            Asynchronous operations may allocate memory. [<span class="emphasis"><em>Note:</em></span>
            Such as a data structure to store copies of the <code class="computeroutput"><span class="identifier">completion_handler</span></code>
            object and the initiating function's arguments. &#8212;<span class="emphasis"><em>end note</em></span>]
          </p><p>
            Let <code class="computeroutput"><span class="identifier">Alloc1</span></code> be a type,
            satisfying the <a class="link" href="#requirements.proto_allocator" title="12.3.1.&#160;Proto-allocator requirements"><code class="computeroutput"><span class="identifier">ProtoAllocator</span></code></a> requirements,
            that represents the asynchronous operation's default allocation strategy.
            [<span class="emphasis"><em>Note:</em></span> Typically <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span></code>. &#8212;<span class="emphasis"><em>end note</em></span>] Let
            <code class="computeroutput"><span class="identifier">alloc1</span></code> be a value of
            type <code class="computeroutput"><span class="identifier">Alloc1</span></code>.
          </p><p>
            A completion handler object of type <code class="computeroutput"><span class="identifier">CompletionHandler</span></code>
            has an associated allocator object <code class="computeroutput"><span class="identifier">alloc2</span></code>
            of type <code class="computeroutput"><span class="identifier">Alloc2</span></code> satisfying
            the <a class="link" href="#requirements.proto_allocator" title="12.3.1.&#160;Proto-allocator requirements"><code class="computeroutput"><span class="identifier">ProtoAllocator</span></code></a>
            requirements. The type <code class="computeroutput"><span class="identifier">Alloc2</span></code>
            is <code class="computeroutput"><span class="identifier">associated_allocator_t</span><span class="special">&lt;</span><span class="identifier">CompletionHandler</span><span class="special">,</span> <span class="identifier">Alloc1</span><span class="special">&gt;</span></code>. Let <code class="computeroutput"><span class="identifier">alloc2</span></code>
            be a value of type <code class="computeroutput"><span class="identifier">Alloc2</span></code>
            obtained by performing <code class="computeroutput"><span class="identifier">get_associated_allocator</span><span class="special">(</span><span class="identifier">completion_handler</span><span class="special">,</span> <span class="identifier">alloc1</span><span class="special">)</span></code>.
          </p><p>
            The asynchronous operations defined in this Technical Specification:
          </p><p>
            &#8212; If required, allocate memory using only the completion handler's associated
            allocator.
          </p><p>
            &#8212; Prior to completion handler execution, deallocate any memory allocated
            using the completion handler's associated allocator.
          </p><p>
            [<span class="emphasis"><em>Note:</em></span> The implementation may perform operating
            system or underlying API calls that perform memory allocations not using
            the associated allocator. Invocations of the allocator functions may
            not introduce data races (See C++Std [res.on.data.races]). &#8212;<span class="emphasis"><em>end
            note</em></span>]
          </p></div><div class="section" title="12.3.7.12.&#160;Execution of completion handler on completion of asynchronous operation"><div class="titlepage"><div><div><h5 class="title"><a name="requirements.execution_of_completion_handler_on_completion_of_asynchronous_operation"></a>12.3.7.12.&#160;Execution of completion handler on completion of asynchronous operation</h5></div></div></div><p>
            Let <code class="computeroutput"><span class="identifier">Args</span><span class="special">...</span></code>
            be the argument types of the completion signature <code class="computeroutput"><span class="identifier">Signature</span></code>
            and let <code class="literal"><span class="emphasis"><em>N</em></span></code> be <code class="computeroutput"><span class="keyword">sizeof</span><span class="special">...(</span><span class="identifier">Args</span><span class="special">)</span></code>. Let <code class="literal"><span class="emphasis"><em>i</em></span></code>
            be in the range [<code class="computeroutput"><span class="number">0</span></code>,<code class="literal"><span class="emphasis"><em>N</em></span></code>).
            Let <code class="literal">T<sub><span class="emphasis"><em>i</em></span></sub></code> be the <code class="literal"><span class="emphasis"><em>i</em></span></code>th
            type in <code class="computeroutput"><span class="identifier">Args</span><span class="special">...</span></code>
            and let <code class="literal">t<sub><span class="emphasis"><em>i</em></span></sub></code> be the <code class="literal"><span class="emphasis"><em>i</em></span></code>th
            completion handler argument associated with <code class="literal">T<sub><span class="emphasis"><em>i</em></span></sub></code>.
          </p><p>
            Let <code class="computeroutput"><span class="identifier">f</span></code> be a function object,
            callable as <code class="computeroutput"><span class="identifier">f</span><span class="special">()</span></code>,
            that invokes <code class="computeroutput"><span class="identifier">completion_handler</span></code>
            as if by <code class="literal">completion_handler(forward&lt;T<sub><span class="emphasis"><em>0</em></span></sub>&gt;(t<sub><span class="emphasis"><em>0</em></span></sub>),
            ..., forward&lt;T<sub><span class="emphasis"><em>N-1</em></span></sub>&gt;(t<sub><span class="emphasis"><em>N-1</em></span></sub>))</code>.
          </p><p>
            If an asynchonous operation completes immediately (that is, within the
            thread of execution calling the initiating function, and before the initiating
            function returns), the completion handler shall be submitted for execution
            as if by performing <code class="computeroutput"><span class="identifier">ex2</span><span class="special">.</span><span class="identifier">post</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">alloc2</span><span class="special">)</span></code>. Otherwise, the completion handler shall
            be submitted for execution as if by performing <code class="computeroutput"><span class="identifier">ex2</span><span class="special">.</span><span class="identifier">dispatch</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">alloc2</span><span class="special">)</span></code>.
          </p></div><div class="section" title="12.3.7.13.&#160;Completion handlers and exceptions"><div class="titlepage"><div><div><h5 class="title"><a name="requirements.completion_handlers_and_exceptions"></a>12.3.7.13.&#160;Completion handlers and exceptions</h5></div></div></div><p>
            Completion handlers are permitted to throw exceptions. The effect of
            any exception propagated from the execution of a completion handler is
            determined by the executor which is executing the completion handler.
          </p></div></div></div><div class="section" title="12.4.&#160;Class template async_result"><div class="titlepage"><div><div><h3 class="title"><a name="classes.async_result"></a>12.4.&#160;Class template <code class="literal">async_result</code></h3></div></div></div><p>
        The <code class="computeroutput"><span class="identifier">async_result</span></code> class template
        is a customization point for asynchronous operations. Template parameter
        <code class="computeroutput"><span class="identifier">CompletionToken</span></code> specifies
        the model used to obtain the result of the asynchronous operation. Template
        parameter <code class="computeroutput"><span class="identifier">Signature</span></code> is the
        call signature (C++Std [func.def]) for the completion handler type invoked
        on completion of the asynchronous operation. The <code class="computeroutput"><span class="identifier">async_result</span></code>
        template:
      </p><p>
        &#8212; transforms a <code class="computeroutput"><span class="identifier">CompletionToken</span></code>
        into a completion handler type that is based on a <code class="computeroutput"><span class="identifier">Signature</span></code>;
        and
      </p><p>
        &#8212; determines the return type and return value of an asynchronous operation's
        initiating function.
      </p><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Signature</span><span class="special">,</span> <span class="keyword">class</span> <span class="special">=</span> <span class="keyword">void</span><span class="special">&gt;</span>
  <span class="keyword">class</span> <span class="identifier">async_result</span>
  <span class="special">{</span>
  <span class="keyword">public</span><span class="special">:</span>
    <span class="keyword">typedef</span> <span class="identifier">CompletionToken</span> <span class="identifier">completion_handler_type</span><span class="special">;</span>
    <span class="keyword">typedef</span> <span class="keyword">void</span> <span class="identifier">return_type</span><span class="special">;</span>

    <span class="keyword">explicit</span> <span class="identifier">async_result</span><span class="special">(</span><span class="identifier">completion_handler_type</span><span class="special">&amp;)</span> <span class="special">{}</span>
    <span class="identifier">async_result</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">async_result</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
    <span class="identifier">async_result</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">async_result</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>

    <span class="identifier">return_type</span> <span class="identifier">get</span><span class="special">()</span> <span class="special">{}</span>
  <span class="special">};</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>
</pre><p>
        The template parameter <code class="computeroutput"><span class="identifier">CompletionToken</span></code>
        shall be an object type. The template parameter <code class="computeroutput"><span class="identifier">Signature</span></code>
        shall be a call signature (C++Std [func.def]).
      </p><p>
        Specializations of <code class="computeroutput"><span class="identifier">async_result</span></code>
        shall satisfy the <code class="computeroutput"><span class="identifier">Destructible</span></code>
        requirements (C++Std [destructible]) in addition to the requirements in the
        table below. In this table, <code class="computeroutput"><span class="identifier">R</span></code>
        is a specialization of <code class="computeroutput"><span class="identifier">async_result</span></code>;
        <code class="computeroutput"><span class="identifier">r</span></code> is a modifiable lvalue
        of type <code class="computeroutput"><span class="identifier">R</span></code>; and <code class="computeroutput"><span class="identifier">h</span></code> is a modifiable lvalue of type <code class="computeroutput"><span class="identifier">R</span><span class="special">::</span><span class="identifier">completion_handler_type</span></code>.
      </p><div class="table"><a name="classes.proposed_text.async_result.t0"></a><p class="title"><b>Table&#160;6.&#160;async_result specialization requirements</b></p><div class="table-contents"><table class="table" summary="async_result specialization requirements"><colgroup><col><col><col></colgroup><thead><tr><th>
                <p>
                  Expression
                </p>
              </th><th>
                <p>
                  Return type
                </p>
              </th><th>
                <p>
                  Requirement
                </p>
              </th></tr></thead><tbody><tr><td>
                <p>
                  <code class="computeroutput"><span class="identifier">R</span><span class="special">::</span><span class="identifier">completion_handler_type</span></code>
                </p>
              </td><td>
              </td><td>
                <p>
                  A type satisfying <code class="computeroutput"><span class="identifier">MoveConstructible</span></code>
                  requirements (C++Std [moveconstructible]), An object of type <code class="computeroutput"><span class="identifier">completion_handler_type</span></code> shall
                  be a function object with call signature <code class="computeroutput"><span class="identifier">Signature</span></code>,
                  and <code class="computeroutput"><span class="identifier">completion_handler_type</span></code>
                  shall be constructible with an rvalue of type <code class="computeroutput"><span class="identifier">CompletionToken</span></code>.
                </p>
              </td></tr><tr><td>
                <p>
                  <code class="computeroutput"><span class="identifier">R</span><span class="special">::</span><span class="identifier">return_type</span></code>
                </p>
              </td><td>
              </td><td>
                <p>
                  <code class="computeroutput"><span class="keyword">void</span></code>; or a type satisfying
                  <code class="computeroutput"><span class="identifier">MoveConstructible</span></code>
                  requirements (C++Std [moveconstructible])
                </p>
              </td></tr><tr><td>
                <p>
                  <code class="computeroutput"><span class="identifier">R</span> <span class="identifier">r</span><span class="special">(</span><span class="identifier">h</span><span class="special">);</span></code>
                </p>
              </td><td>
              </td><td>
              </td></tr><tr><td>
                <p>
                  <code class="computeroutput"><span class="identifier">r</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span></code>
                </p>
              </td><td>
                <p>
                  <code class="computeroutput"><span class="identifier">R</span><span class="special">::</span><span class="identifier">return_type</span></code>
                </p>
              </td><td>
                <p>
                  [<span class="emphasis"><em>Note:</em></span> An asynchronous operation's initiating
                  function uses the <code class="computeroutput"><span class="identifier">get</span><span class="special">()</span></code> member function as the sole operand
                  of a return statement. &#8212;<span class="emphasis"><em>end note</em></span>]
                </p>
              </td></tr></tbody></table></div></div><br class="table-break"></div><div class="section" title="12.5.&#160;Class template async_completion"><div class="titlepage"><div><div><h3 class="title"><a name="classes.async_completion"></a>12.5.&#160;Class template <code class="literal">async_completion</code></h3></div></div></div><p>
        Class template <code class="computeroutput"><span class="identifier">async_completion</span></code>
        is provided as a convenience, to simplify the implementation of asynchronous
        operations that use <code class="computeroutput"><span class="identifier">async_result</span></code>.
      </p><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Signature</span><span class="special">&gt;</span>
  <span class="keyword">struct</span> <span class="identifier">async_completion</span>
  <span class="special">{</span>
    <span class="keyword">typedef</span> <span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">decay_t</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;,</span>
      <span class="identifier">Signature</span><span class="special">&gt;::</span><span class="identifier">completion_handler_type</span>
        <span class="identifier">completion_handler_type</span><span class="special">;</span>

    <span class="keyword">explicit</span> <span class="identifier">async_completion</span><span class="special">(</span><span class="identifier">CompletionToken</span><span class="special">&amp;</span> <span class="identifier">t</span><span class="special">);</span>
    <span class="identifier">async_completion</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">async_completion</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
    <span class="identifier">async_completion</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">async_completion</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>

    <span class="emphasis"><em>see below</em></span> <span class="identifier">completion_handler</span><span class="special">;</span>
    <span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">decay_t</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;,</span> <span class="identifier">Signature</span><span class="special">&gt;</span> <span class="identifier">result</span><span class="special">;</span>
  <span class="special">};</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>
</pre><p>
        The template parameter <code class="computeroutput"><span class="identifier">Signature</span></code>
        shall be a call signature (C++Std [func.def]).
      </p><pre class="programlisting"><span class="keyword">explicit</span> <span class="identifier">async_completion</span><span class="special">(</span><span class="identifier">CompletionToken</span><span class="special">&amp;</span> <span class="identifier">t</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Effects:</em></span> If <code class="computeroutput"><span class="identifier">CompletionToken</span></code>
          and <code class="computeroutput"><span class="identifier">completion_handler_type</span></code>
          are the same type, binds <code class="computeroutput"><span class="identifier">completion_handler</span></code>
          to <code class="computeroutput"><span class="identifier">t</span></code>; otherwise, initializes
          <code class="computeroutput"><span class="identifier">completion_handler</span></code> with
          the result of <code class="computeroutput"><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;(</span><span class="identifier">t</span><span class="special">)</span></code>. Initializes
          <code class="computeroutput"><span class="identifier">result</span></code> with <code class="computeroutput"><span class="identifier">completion_handler</span></code>.
        </p></blockquote></div><pre class="programlisting"><span class="emphasis"><em>see below</em></span> <span class="identifier">completion_handler</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Type:</em></span> <code class="computeroutput"><span class="identifier">completion_handler_type</span><span class="special">&amp;</span></code> if <code class="computeroutput"><span class="identifier">CompletionToken</span></code>
          and <code class="computeroutput"><span class="identifier">completion_handler_type</span></code>
          are the same type; otherwise, <code class="computeroutput"><span class="identifier">completion_handler_type</span></code>.
        </p></blockquote></div></div><div class="section" title="12.6.&#160;Class template associated_allocator"><div class="titlepage"><div><div><h3 class="title"><a name="classes.associated_allocator"></a>12.6.&#160;Class template <code class="literal">associated_allocator</code></h3></div></div></div><p>
        Class template <code class="computeroutput"><span class="identifier">associated_allocator</span></code>
        is an <a class="link" href="#requirements.associator" title="12.3.6.&#160;Associator requirements">associator</a> for the
        <a class="link" href="#requirements.proto_allocator" title="12.3.1.&#160;Proto-allocator requirements"><code class="computeroutput"><span class="identifier">ProtoAllocator</span></code></a>
        type requirements, with default candidate type <code class="computeroutput"><span class="identifier">allocator</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span></code>
        and default candidate object <code class="computeroutput"><span class="identifier">allocator</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;()</span></code>.
      </p><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span> <span class="special">=</span> <span class="identifier">allocator</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;&gt;</span>
  <span class="keyword">struct</span> <span class="identifier">associated_allocator</span>
  <span class="special">{</span>
    <span class="keyword">typedef</span> <span class="emphasis"><em>see below</em></span> <span class="identifier">type</span><span class="special">;</span>

    <span class="keyword">static</span> <span class="identifier">type</span> <span class="identifier">get</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">ProtoAllocator</span><span class="special">())</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="special">};</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>
</pre><p>
        Specializations of <code class="computeroutput"><span class="identifier">associated_allocator</span></code>
        shall satisfy the requirements in the table below. In this table, <code class="computeroutput"><span class="identifier">X</span></code> is a specialization of <code class="computeroutput"><span class="identifier">associated_allocator</span></code> for the template parameters
        <code class="computeroutput"><span class="identifier">T</span></code> and <code class="computeroutput"><span class="identifier">ProtoAllocator</span></code>;
        <code class="computeroutput"><span class="identifier">t</span></code> is a value of (possibly
        const) <code class="computeroutput"><span class="identifier">T</span></code>; and <code class="computeroutput"><span class="identifier">a</span></code> is an object of type <code class="computeroutput"><span class="identifier">ProtoAllocator</span></code>.
      </p><div class="table"><a name="classes.proposed_text.associated_allocator.t0"></a><p class="title"><b>Table&#160;7.&#160;associated_allocator specialization requirements</b></p><div class="table-contents"><table class="table" summary="associated_allocator specialization requirements"><colgroup><col><col><col></colgroup><thead><tr><th>
                <p>
                  Expression
                </p>
              </th><th>
                <p>
                  Return type
                </p>
              </th><th>
                <p>
                  Note
                </p>
              </th></tr></thead><tbody><tr><td>
                <p>
                  <code class="computeroutput"><span class="keyword">typename</span> <span class="identifier">X</span><span class="special">::</span><span class="identifier">type</span></code>
                </p>
              </td><td>
                <p>
                  A type meeting the <a class="link" href="#requirements.proto_allocator" title="12.3.1.&#160;Proto-allocator requirements">proto-allocator</a>
                  requirements.
                </p>
              </td><td>
              </td></tr><tr><td>
                <p>
                  <code class="computeroutput"><span class="identifier">X</span><span class="special">::</span><span class="identifier">get</span><span class="special">(</span><span class="identifier">t</span><span class="special">)</span></code>
                </p>
              </td><td>
                <p>
                  <code class="computeroutput"><span class="identifier">X</span><span class="special">::</span><span class="identifier">type</span></code>
                </p>
              </td><td>
                <p>
                  Shall not exit via an exception.<br> Equivalent to <code class="computeroutput"><span class="identifier">X</span><span class="special">::</span><span class="identifier">get</span><span class="special">(</span><span class="identifier">t</span><span class="special">,</span>
                  <span class="identifier">ProtoAllocator</span><span class="special">())</span></code>.
                </p>
              </td></tr><tr><td>
                <p>
                  <code class="computeroutput"><span class="identifier">X</span><span class="special">::</span><span class="identifier">get</span><span class="special">(</span><span class="identifier">t</span><span class="special">,</span>
                  <span class="identifier">a</span><span class="special">)</span></code>
                </p>
              </td><td>
                <p>
                  <code class="computeroutput"><span class="identifier">X</span><span class="special">::</span><span class="identifier">type</span></code>
                </p>
              </td><td>
                <p>
                  Shall not exit via an exception.
                </p>
              </td></tr></tbody></table></div></div><br class="table-break"><div class="section" title="12.6.1.&#160;associated_allocator members"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__associated_allocator__members"></a>12.6.1.&#160;<code class="literal">associated_allocator</code> members</h4></div></div></div><pre class="programlisting"><span class="keyword">typedef</span> <span class="emphasis"><em>see below</em></span> <span class="identifier">type</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Type:</em></span> If <code class="computeroutput"><span class="identifier">T</span></code>
            has a nested type <code class="computeroutput"><span class="identifier">allocator_type</span></code>,
            <code class="computeroutput"><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">::</span><span class="identifier">allocator_type</span></code>.
            Otherwise <code class="computeroutput"><span class="identifier">ProtoAllocator</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">type</span> <span class="identifier">get</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">ProtoAllocator</span><span class="special">())</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> If <code class="computeroutput"><span class="identifier">T</span></code>
            has a nested type <code class="computeroutput"><span class="identifier">allocator_type</span></code>,
            <code class="computeroutput"><span class="identifier">t</span><span class="special">.</span><span class="identifier">get_allocator</span><span class="special">()</span></code>.
            Otherwise <code class="computeroutput"><span class="identifier">a</span></code>.
          </p></blockquote></div></div></div><div class="section" title="12.7.&#160;Function get_associated_allocator"><div class="titlepage"><div><div><h3 class="title"><a name="functions.get_associated_allocator"></a>12.7.&#160;Function <code class="literal">get_associated_allocator</code></h3></div></div></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
  <span class="identifier">associated_allocator_t</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">get_associated_allocator</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">t</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">associated_allocator</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">get</span><span class="special">(</span><span class="identifier">t</span><span class="special">)</span></code>.
        </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
  <span class="identifier">associated_allocator_t</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
    <span class="identifier">get_associated_allocator</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">associated_allocator</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;::</span><span class="identifier">get</span><span class="special">(</span><span class="identifier">t</span><span class="special">,</span>
          <span class="identifier">a</span><span class="special">)</span></code>.
        </p></blockquote></div></div><div class="section" title="12.8.&#160;Class execution_context"><div class="titlepage"><div><div><h3 class="title"><a name="classes.execution_context"></a>12.8.&#160;Class <code class="literal">execution_context</code></h3></div></div></div><p>
        Class <code class="computeroutput"><span class="identifier">execution_context</span></code> implements
        an extensible, type-safe, polymorphic set of services, indexed by service
        type.
      </p><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">class</span> <span class="identifier">execution_context</span>
  <span class="special">{</span>
  <span class="keyword">public</span><span class="special">:</span>
    <span class="keyword">class</span> <a class="link" href="#classes.execution_context__service" title="12.9.&#160;Class execution_context::service">service</a><span class="special">;</span>

    <span class="comment">// construct / copy / destroy:</span>

    <span class="identifier">execution_context</span><span class="special">();</span>
    <span class="identifier">execution_context</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">execution_context</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
    <span class="identifier">execution_context</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">execution_context</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
    <span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">execution_context</span><span class="special">();</span>

    <span class="comment">// execution context operations:</span>

    <span class="keyword">void</span> <span class="identifier">notify_fork</span><span class="special">(</span><span class="identifier">fork_event</span> <span class="identifier">e</span><span class="special">);</span>

  <span class="keyword">protected</span><span class="special">:</span>

    <span class="comment">// execution context protected operations:</span>

    <span class="keyword">void</span> <span class="identifier">shutdown</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">void</span> <span class="identifier">destroy</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="special">};</span>

  <span class="comment">// service access:</span>
  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Service</span><span class="special">&gt;</span> <span class="keyword">typename</span> <span class="identifier">Service</span><span class="special">::</span><span class="identifier">key_type</span><span class="special">&amp;</span>
    <span class="identifier">use_service</span><span class="special">(</span><span class="identifier">execution_context</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">);</span>
  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Service</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="identifier">Service</span><span class="special">&amp;</span>
    <span class="identifier">make_service</span><span class="special">(</span><span class="identifier">execution_context</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">,</span> <span class="identifier">Args</span><span class="special">&amp;&amp;...</span> <span class="identifier">args</span><span class="special">);</span>
  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Service</span><span class="special">&gt;</span> <span class="keyword">bool</span> <span class="identifier">has_service</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">execution_context</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="keyword">class</span> <span class="identifier">service_already_exists</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">logic_error</span> <span class="special">{</span> <span class="special">};</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>
</pre><p>
        Access to the services of an <code class="computeroutput"><span class="identifier">execution_context</span></code>
        is via three function templates, <code class="computeroutput"><span class="identifier">use_service</span><span class="special">&lt;&gt;</span></code>, <code class="computeroutput"><span class="identifier">make_service</span><span class="special">&lt;&gt;</span></code> and <code class="computeroutput"><span class="identifier">has_service</span><span class="special">&lt;&gt;</span></code>.
      </p><p>
        In a call to <code class="computeroutput"><span class="identifier">use_service</span><span class="special">&lt;</span><span class="identifier">Service</span><span class="special">&gt;()</span></code>, the type argument chooses a service.
        If the service is not present in an <code class="computeroutput"><span class="identifier">execution_context</span></code>,
        an object of type <code class="computeroutput"><span class="identifier">Service</span></code>
        is created and added to the <code class="computeroutput"><span class="identifier">execution_context</span></code>.
        A program can check if an <code class="computeroutput"><span class="identifier">execution_context</span></code>
        implements a particular service with the function template <code class="computeroutput"><span class="identifier">has_service</span><span class="special">&lt;</span><span class="identifier">Service</span><span class="special">&gt;()</span></code>.
      </p><p>
        Service objects may be explicitly added to an <code class="computeroutput"><span class="identifier">execution_context</span></code>
        using the function template <code class="computeroutput"><span class="identifier">make_service</span><span class="special">&lt;</span><span class="identifier">Service</span><span class="special">&gt;()</span></code>. If the service is already present,
        <code class="computeroutput"><span class="identifier">make_service</span></code> exits via an
        exception of type <code class="computeroutput"><span class="identifier">service_already_exists</span></code>.
      </p><p>
        Once a service reference is obtained from an <code class="computeroutput"><span class="identifier">execution_context</span></code>
        object by calling <code class="computeroutput"><span class="identifier">use_service</span><span class="special">&lt;&gt;</span></code>, that reference remains usable until
        a call to <code class="computeroutput"><span class="identifier">destroy</span><span class="special">()</span></code>.
      </p><div class="section" title="12.8.1.&#160;execution_context constructor"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__execution_context__constructor"></a>12.8.1.&#160;<code class="literal">execution_context</code> constructor</h4></div></div></div><pre class="programlisting"><span class="identifier">execution_context</span><span class="special">();</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Creates an object of class <code class="computeroutput"><span class="identifier">execution_context</span></code> which contains no
            services. [<span class="emphasis"><em>Note:</em></span> An implementation might preload
            services of internal service types for its own use. &#8212;<span class="emphasis"><em>end note</em></span>]
          </p></blockquote></div></div><div class="section" title="12.8.2.&#160;execution_context destructor"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__execution_context__destructor"></a>12.8.2.&#160;<code class="literal">execution_context</code> destructor</h4></div></div></div><pre class="programlisting"><span class="special">~</span><span class="identifier">execution_context</span><span class="special">();</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Destroys an object of class <code class="computeroutput"><span class="identifier">execution_context</span></code>. Performs <code class="computeroutput"><span class="identifier">shutdown</span><span class="special">()</span></code>
            followed by <code class="computeroutput"><span class="identifier">destroy</span><span class="special">()</span></code>.
          </p></blockquote></div></div><div class="section" title="12.8.3.&#160;execution_context operations"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__execution_context__operations"></a>12.8.3.&#160;<code class="literal">execution_context</code> operations</h4></div></div></div><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">notify_fork</span><span class="special">(</span><span class="identifier">fork_event</span> <span class="identifier">e</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> For each service object <code class="computeroutput"><span class="identifier">svc</span></code>
            in the set:<br> &#8212; If <code class="computeroutput"><span class="identifier">e</span> <span class="special">==</span> <span class="identifier">fork_event</span><span class="special">::</span><span class="identifier">prepare</span></code>,
            performs <code class="computeroutput"><span class="identifier">svc</span><span class="special">-&gt;</span><span class="identifier">notify_fork</span><span class="special">(</span><span class="identifier">e</span><span class="special">)</span></code>
            in reverse order of addition to the set.<br> &#8212; Otherwise, performs <code class="computeroutput"><span class="identifier">svc</span><span class="special">-&gt;</span><span class="identifier">notify_fork</span><span class="special">(</span><span class="identifier">e</span><span class="special">)</span></code>
            in order of addition to the set.
          </p></blockquote></div></div><div class="section" title="12.8.4.&#160;execution_context protected operations"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__execution_context__protected_operations"></a>12.8.4.&#160;<code class="literal">execution_context</code> protected operations</h4></div></div></div><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">shutdown</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> For each service object <code class="computeroutput"><span class="identifier">svc</span></code>
            in the <code class="computeroutput"><span class="identifier">execution_context</span></code>
            set, in reverse order of addition to the set, performs <code class="computeroutput"><span class="identifier">svc</span><span class="special">-&gt;</span><span class="identifier">shutdown</span><span class="special">()</span></code>.
            For each service in the set, <code class="computeroutput"><span class="identifier">svc</span><span class="special">-&gt;</span><span class="identifier">shutdown</span><span class="special">()</span></code> is called only once irrespective of
            the number of calls to <code class="computeroutput"><span class="identifier">shutdown</span></code>
            on the <code class="computeroutput"><span class="identifier">execution_context</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">destroy</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Destroys each service object in the <code class="computeroutput"><span class="identifier">execution_context</span></code> set, and removes
            it from the set, in reverse order of addition to the set.
          </p></blockquote></div></div><div class="section" title="12.8.5.&#160;execution_context globals"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__execution_context__globals"></a>12.8.5.&#160;<code class="literal">execution_context</code> globals</h4></div></div></div><p>
          The functions <code class="computeroutput"><span class="identifier">use_service</span></code>,
          <code class="computeroutput"><span class="identifier">make_service</span></code>, and <code class="computeroutput"><span class="identifier">has_service</span></code> do not introduce data races
          as a result of concurrent calls to those functions from different threads.
        </p><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Service</span><span class="special">&gt;</span> <span class="keyword">typename</span> <span class="identifier">Service</span><span class="special">::</span><span class="identifier">key_type</span><span class="special">&amp;</span>
  <span class="identifier">use_service</span><span class="special">(</span><span class="identifier">execution_context</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> If an object of type <code class="computeroutput"><span class="identifier">Service</span><span class="special">::</span><span class="identifier">key_type</span></code>
            does not already exist in the <code class="computeroutput"><span class="identifier">execution_context</span></code>
            set identified by <code class="computeroutput"><span class="identifier">ctx</span></code>,
            creates an object of type <code class="computeroutput"><span class="identifier">Service</span></code>,
            initialized as <code class="computeroutput"><span class="identifier">Service</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">)</span></code>, and adds it to the set.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> A reference to the corresponding service
            of <code class="computeroutput"><span class="identifier">ctx</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Notes:</em></span> The reference returned remains valid until
            a call to <code class="computeroutput"><span class="identifier">destroy</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Service</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="identifier">Service</span><span class="special">&amp;</span>
  <span class="identifier">make_service</span><span class="special">(</span><span class="identifier">execution_context</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">,</span> <span class="identifier">Args</span><span class="special">&amp;&amp;...</span> <span class="identifier">args</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Requires:</em></span> A service object of type <code class="computeroutput"><span class="identifier">Service</span><span class="special">::</span><span class="identifier">key_type</span></code> does not already exist in
            the <code class="computeroutput"><span class="identifier">execution_context</span></code>
            set identified by <code class="computeroutput"><span class="identifier">ctx</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Creates an object of type <code class="computeroutput"><span class="identifier">Service</span></code>, initialized as <code class="computeroutput"><span class="identifier">Service</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">,</span> <span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Args</span><span class="special">&gt;(</span><span class="identifier">args</span><span class="special">)</span>...<span class="special">)</span></code>, and adds it to the <code class="computeroutput"><span class="identifier">execution_context</span></code>
            set identified by <code class="computeroutput"><span class="identifier">ctx</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Throws:</em></span> <code class="computeroutput"><span class="identifier">service_already_exists</span></code>
            if a corresponding service object of type <code class="computeroutput"><span class="identifier">Key</span></code>
            is already present in the set.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Notes:</em></span> The reference returned remains valid until
            a call to <code class="computeroutput"><span class="identifier">destroy</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Service</span><span class="special">&gt;</span> <span class="keyword">bool</span> <span class="identifier">has_service</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">execution_context</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="keyword">true</span></code>
            if an object of type <code class="computeroutput"><span class="identifier">Service</span><span class="special">::</span><span class="identifier">key_type</span></code>
            is present in <code class="computeroutput"><span class="identifier">ctx</span></code>, otherwise
            <code class="computeroutput"><span class="keyword">false</span></code>.
          </p></blockquote></div></div></div><div class="section" title="12.9.&#160;Class execution_context::service"><div class="titlepage"><div><div><h3 class="title"><a name="classes.execution_context__service"></a>12.9.&#160;Class <code class="literal">execution_context::service</code></h3></div></div></div><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">class</span> <span class="identifier">execution_context</span><span class="special">::</span><span class="identifier">service</span>
  <span class="special">{</span>
  <span class="keyword">protected</span><span class="special">:</span>
    <span class="comment">// construct / copy / destroy:</span>

    <span class="keyword">explicit</span> <span class="identifier">service</span><span class="special">(</span><span class="identifier">execution_context</span><span class="special">&amp;</span> <span class="identifier">owner</span><span class="special">);</span>
    <span class="identifier">service</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">service</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
    <span class="identifier">service</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">service</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
    <span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">service</span><span class="special">();</span>

    <span class="comment">// service observers:</span>

    <span class="identifier">execution_context</span><span class="special">&amp;</span> <span class="identifier">context</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>

  <span class="keyword">private</span><span class="special">:</span>
    <span class="comment">// service operations:</span>

    <span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">shutdown</span><span class="special">()</span> <span class="keyword">noexcept</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
    <span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">notify_fork</span><span class="special">(</span><span class="identifier">fork_event</span> <span class="identifier">e</span><span class="special">)</span> <span class="special">{}</span>

    <span class="identifier">execution_context</span><span class="special">&amp;</span> <span class="identifier">context_</span><span class="special">;</span> <span class="comment">// <span class="emphasis"><em>exposition only</em></span></span>
  <span class="special">};</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>

<span class="keyword">explicit</span> <span class="identifier">service</span><span class="special">(</span><span class="identifier">execution_context</span><span class="special">&amp;</span> <span class="identifier">owner</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">addressof</span><span class="special">(</span><span class="identifier">context_</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">addressof</span><span class="special">(</span><span class="identifier">owner</span><span class="special">)</span></code>.
        </p></blockquote></div><pre class="programlisting"><span class="identifier">execution_context</span><span class="special">&amp;</span> <span class="identifier">context</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">context_</span></code>.
        </p></blockquote></div></div><div class="section" title="12.10.&#160;Class template is_executor"><div class="titlepage"><div><div><h3 class="title"><a name="classes.is_executor"></a>12.10.&#160;Class template <code class="literal">is_executor</code></h3></div></div></div><p>
        The class template <code class="computeroutput"><span class="identifier">is_executor</span></code>
        can be used to detect executor types satisfying the <a class="link" href="#requirements.executor" title="12.3.3.&#160;Executor requirements"><code class="computeroutput"><span class="identifier">Executor</span></code></a> type requirements.
      </p><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">is_executor</span><span class="special">;</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>
</pre><p>
        <code class="computeroutput"><span class="identifier">T</span></code> shall be a complete type.
      </p><p>
        Class template <code class="computeroutput"><span class="identifier">is_executor</span></code>
        is a UnaryTypeTrait (C++Std [meta.rqmts]) with a BaseCharacteristic of <code class="computeroutput"><span class="identifier">true_type</span></code> if the type <code class="computeroutput"><span class="identifier">T</span></code>
        meets the syntactic requirements for <a class="link" href="#requirements.executor" title="12.3.3.&#160;Executor requirements"><code class="computeroutput"><span class="identifier">Executor</span></code></a>, otherwise <code class="computeroutput"><span class="identifier">false_type</span></code>.
      </p></div><div class="section" title="12.11.&#160;Executor argument tag"><div class="titlepage"><div><div><h3 class="title"><a name="classes.executor_arg_t"></a>12.11.&#160;Executor argument tag</h3></div></div></div><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">struct</span> <span class="identifier">executor_arg_t</span> <span class="special">{</span> <span class="special">};</span>
  <span class="keyword">constexpr</span> <span class="identifier">executor_arg_t</span> <span class="identifier">executor_arg</span> <span class="special">=</span> <span class="identifier">executor_arg_t</span><span class="special">();</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>
</pre><p>
        The <code class="computeroutput"><span class="identifier">executor_arg_t</span></code> struct
        is an empty structure type used as a unique type to disambiguate constructor
        and function overloading. Specifically, types may have constructors with
        <code class="computeroutput"><span class="identifier">executor_arg_t</span></code> as the first
        argument, immediately followed by an argument of a type that satisfies the
        <a class="link" href="#requirements.executor" title="12.3.3.&#160;Executor requirements">Executor requirements</a>.
      </p></div><div class="section" title="12.12.&#160;uses_executor"><div class="titlepage"><div><div><h3 class="title"><a name="classes.uses_executor"></a>12.12.&#160;<code class="literal">uses_executor</code></h3></div></div></div><div class="section" title="12.12.1.&#160;uses_executor trait"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__uses_executor__trait"></a>12.12.1.&#160;<code class="literal">uses_executor</code> trait</h4></div></div></div><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">uses_executor</span><span class="special">;</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>
</pre><p>
          <span class="emphasis"><em>Remark:</em></span> Detects whether <code class="computeroutput"><span class="identifier">T</span></code>
          has a nested <code class="computeroutput"><span class="identifier">executor_type</span></code>
          that is convertible from <code class="computeroutput"><span class="identifier">Executor</span></code>.
          Meets the <code class="computeroutput"><span class="identifier">BinaryTypeTrait</span></code>
          requirements (C++Std [meta.rqmts]). The implementation provides a definition
          that is derived from <code class="computeroutput"><span class="identifier">true_type</span></code>
          if a type <code class="computeroutput"><span class="identifier">T</span><span class="special">::</span><span class="identifier">executor_type</span></code> exists and <code class="computeroutput"><span class="identifier">is_convertible</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">,</span> <span class="identifier">T</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&gt;::</span><span class="identifier">value</span>
          <span class="special">!=</span> <span class="keyword">false</span></code>,
          otherwise it is derived from <code class="computeroutput"><span class="identifier">false_type</span></code>.
          A program may specialize this template to derive from <code class="computeroutput"><span class="identifier">true_type</span></code>
          for a user-defined type <code class="computeroutput"><span class="identifier">T</span></code>
          that does not have a nested <code class="computeroutput"><span class="identifier">executor_type</span></code>
          but nonetheless can be constructed with an executor if the first argument
          of a constructor has type <code class="computeroutput"><span class="identifier">executor_arg_t</span></code>
          and the second argument has type <code class="computeroutput"><span class="identifier">Executor</span></code>.
        </p></div><div class="section" title="12.12.2.&#160;uses-executor construction"><div class="titlepage"><div><div><h4 class="title"><a name="classes.uses_executor_construction"></a>12.12.2.&#160;uses-executor construction</h4></div></div></div><p>
          <span class="emphasis"><em>Uses-executor construction</em></span> with executor <code class="computeroutput"><span class="identifier">Executor</span></code> refers to the construction of
          an object <code class="computeroutput"><span class="identifier">obj</span></code> of type
          <code class="computeroutput"><span class="identifier">T</span></code>, using constructor arguments
          <code class="computeroutput"><span class="identifier">v1</span><span class="special">,</span>
          <span class="identifier">v2</span><span class="special">,</span>
          <span class="special">...,</span> <span class="identifier">vN</span></code>
          of types <code class="computeroutput"><span class="identifier">V1</span><span class="special">,</span>
          <span class="identifier">V2</span><span class="special">,</span>
          <span class="special">...,</span> <span class="identifier">VN</span></code>,
          respectively, and an executor <code class="computeroutput"><span class="identifier">ex</span></code>
          of type <code class="computeroutput"><span class="identifier">Executor</span></code>, according
          to the following rules:
        </p><p>
          &#8212; if <code class="computeroutput"><span class="identifier">uses_executor</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">&gt;::</span><span class="identifier">value</span></code>
          is <code class="computeroutput"><span class="keyword">true</span></code> and <code class="computeroutput"><span class="identifier">is_constructible</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">executor_arg_t</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">,</span> <span class="identifier">V1</span><span class="special">,</span> <span class="identifier">V2</span><span class="special">,</span> <span class="special">...,</span> <span class="identifier">VN</span><span class="special">&gt;::</span><span class="identifier">value</span></code> is <code class="computeroutput"><span class="keyword">true</span></code>,
          then <code class="computeroutput"><span class="identifier">obj</span></code> is initialized
          as <code class="computeroutput"><span class="identifier">obj</span><span class="special">(</span><span class="identifier">executor_arg</span><span class="special">,</span>
          <span class="identifier">ex</span><span class="special">,</span>
          <span class="identifier">v1</span><span class="special">,</span>
          <span class="identifier">v2</span><span class="special">,</span>
          <span class="special">...,</span> <span class="identifier">vN</span><span class="special">)</span></code>;
        </p><p>
          &#8212; otherwise, <code class="computeroutput"><span class="identifier">obj</span></code> is initialized
          as <code class="computeroutput"><span class="identifier">obj</span><span class="special">(</span><span class="identifier">v1</span><span class="special">,</span> <span class="identifier">v2</span><span class="special">,</span> <span class="special">...,</span> <span class="identifier">vN</span><span class="special">)</span></code>.
        </p></div></div><div class="section" title="12.13.&#160;Class template associated_executor"><div class="titlepage"><div><div><h3 class="title"><a name="classes.associated_executor"></a>12.13.&#160;Class template <code class="literal">associated_executor</code></h3></div></div></div><p>
        Class template <code class="computeroutput"><span class="identifier">associated_allocator</span></code>
        is an <a class="link" href="#requirements.associator" title="12.3.6.&#160;Associator requirements">associator</a> for the
        <a class="link" href="#requirements.executor" title="12.3.3.&#160;Executor requirements"><code class="computeroutput"><span class="identifier">Executor</span></code></a>
        type requirements, with default candidate type <code class="computeroutput"><span class="identifier">system_executor</span></code>
        and default candidate object <code class="computeroutput"><span class="identifier">system_executor</span><span class="special">()</span></code>.
      </p><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Executor</span> <span class="special">=</span> <span class="identifier">system_executor</span><span class="special">&gt;</span>
  <span class="keyword">struct</span> <span class="identifier">associated_executor</span>
  <span class="special">{</span>
    <span class="keyword">typedef</span> <span class="emphasis"><em>see below</em></span> <span class="identifier">type</span><span class="special">;</span>

    <span class="keyword">static</span> <span class="identifier">type</span> <span class="identifier">get</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">&amp;</span> <span class="identifier">e</span> <span class="special">=</span> <span class="identifier">Executor</span><span class="special">())</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="special">};</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>
</pre><p>
        Specializations of <code class="computeroutput"><span class="identifier">associated_executor</span></code>
        shall satisfy the requirements in the table below. In this table, <code class="computeroutput"><span class="identifier">X</span></code> is a specialization of <code class="computeroutput"><span class="identifier">associated_executor</span></code> for the template parameters
        <code class="computeroutput"><span class="identifier">T</span></code> and <code class="computeroutput"><span class="identifier">Executor</span></code>;
        <code class="computeroutput"><span class="identifier">t</span></code> is a value of (possibly
        const) <code class="computeroutput"><span class="identifier">T</span></code>; and <code class="computeroutput"><span class="identifier">e</span></code> is an object of type <code class="computeroutput"><span class="identifier">Executor</span></code>.
      </p><div class="table"><a name="classes.proposed_text.associated_executor.t0"></a><p class="title"><b>Table&#160;8.&#160;associated_executor specialization requirements</b></p><div class="table-contents"><table class="table" summary="associated_executor specialization requirements"><colgroup><col><col><col></colgroup><thead><tr><th>
                <p>
                  Expression
                </p>
              </th><th>
                <p>
                  Return type
                </p>
              </th><th>
                <p>
                  Note
                </p>
              </th></tr></thead><tbody><tr><td>
                <p>
                  <code class="computeroutput"><span class="keyword">typename</span> <span class="identifier">X</span><span class="special">::</span><span class="identifier">type</span></code>
                </p>
              </td><td>
                <p>
                  A type meeting <a class="link" href="#requirements.executor" title="12.3.3.&#160;Executor requirements">Executor requirements</a>.
                </p>
              </td><td>
              </td></tr><tr><td>
                <p>
                  <code class="computeroutput"><span class="identifier">X</span><span class="special">::</span><span class="identifier">get</span><span class="special">(</span><span class="identifier">t</span><span class="special">)</span></code>
                </p>
              </td><td>
                <p>
                  <code class="computeroutput"><span class="identifier">X</span><span class="special">::</span><span class="identifier">type</span></code>
                </p>
              </td><td>
                <p>
                  Shall not exit via an exception.<br> Equivalent to <code class="computeroutput"><span class="identifier">X</span><span class="special">::</span><span class="identifier">get</span><span class="special">(</span><span class="identifier">t</span><span class="special">,</span>
                  <span class="identifier">Executor</span><span class="special">())</span></code>.
                </p>
              </td></tr><tr><td>
                <p>
                  <code class="computeroutput"><span class="identifier">X</span><span class="special">::</span><span class="identifier">get</span><span class="special">(</span><span class="identifier">t</span><span class="special">,</span>
                  <span class="identifier">e</span><span class="special">)</span></code>
                </p>
              </td><td>
                <p>
                  <code class="computeroutput"><span class="identifier">X</span><span class="special">::</span><span class="identifier">type</span></code>
                </p>
              </td><td>
                <p>
                  Shall not exit via an exception.
                </p>
              </td></tr></tbody></table></div></div><br class="table-break"><div class="section" title="12.13.1.&#160;associated_executor members"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__associated_executor__members"></a>12.13.1.&#160;<code class="literal">associated_executor</code> members</h4></div></div></div><pre class="programlisting"><span class="keyword">typedef</span> <span class="emphasis"><em>see below</em></span> <span class="identifier">type</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Type:</em></span> If <code class="computeroutput"><span class="identifier">T</span></code>
            has a nested type <code class="computeroutput"><span class="identifier">executor_type</span></code>,
            <code class="computeroutput"><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">::</span><span class="identifier">executor_type</span></code>.
            Otherwise <code class="computeroutput"><span class="identifier">Executor</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">type</span> <span class="identifier">get</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">&amp;</span> <span class="identifier">e</span> <span class="special">=</span> <span class="identifier">Executor</span><span class="special">())</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> If <code class="computeroutput"><span class="identifier">T</span></code>
            has a nested type <code class="computeroutput"><span class="identifier">executor_type</span></code>,
            <code class="computeroutput"><span class="identifier">t</span><span class="special">.</span><span class="identifier">get_executor</span><span class="special">()</span></code>.
            Otherwise <code class="computeroutput"><span class="identifier">e</span></code>.
          </p></blockquote></div></div></div><div class="section" title="12.14.&#160;Function get_associated_executor"><div class="titlepage"><div><div><h3 class="title"><a name="functions.get_associated_executor"></a>12.14.&#160;Function <code class="literal">get_associated_executor</code></h3></div></div></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
  <span class="identifier">associated_executor_t</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">get_associated_executor</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">t</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">associated_executor</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">get</span><span class="special">(</span><span class="identifier">t</span><span class="special">)</span></code>.
        </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
  <span class="identifier">associated_executor_t</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
    <span class="identifier">get_associated_executor</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">&amp;</span> <span class="identifier">ex</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">associated_executor</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">&gt;::</span><span class="identifier">get</span><span class="special">(</span><span class="identifier">t</span><span class="special">,</span>
          <span class="identifier">ex</span><span class="special">)</span></code>.
        </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Remarks:</em></span> This function shall not participate in overload
          resolution unless <code class="computeroutput"><span class="identifier">is_executor</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;::</span><span class="identifier">value</span></code>
          is <code class="computeroutput"><span class="keyword">true</span></code>.
        </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ExecutionContext</span><span class="special">&gt;</span>
  <span class="identifier">associated_executor_t</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">ExecutionContext</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&gt;</span>
    <span class="identifier">get_associated_executor</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">t</span><span class="special">,</span> <span class="identifier">ExecutionContext</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">get_associated_executor</span><span class="special">(</span><span class="identifier">t</span><span class="special">,</span>
          <span class="identifier">ctx</span><span class="special">.</span><span class="identifier">get_executor</span><span class="special">())</span></code>.
        </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Remarks:</em></span> This function shall not participate in overload
          resolution unless <code class="computeroutput"><span class="identifier">is_convertible</span><span class="special">&lt;</span><span class="identifier">ExecutionContext</span><span class="special">&amp;,</span> <span class="identifier">execution_context</span><span class="special">&amp;&gt;::</span><span class="identifier">value</span></code>
          is <code class="computeroutput"><span class="keyword">true</span></code>.
        </p></blockquote></div></div><div class="section" title="12.15.&#160;Class template executor_binder"><div class="titlepage"><div><div><h3 class="title"><a name="classes.executor_binder"></a>12.15.&#160;Class template <code class="literal">executor_binder</code></h3></div></div></div><p>
        <code class="computeroutput"><span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">&gt;</span></code> binds an executor of type <code class="computeroutput"><span class="identifier">Executor</span></code> satisfying <a class="link" href="#requirements.executor" title="12.3.3.&#160;Executor requirements">Executor
        requirements</a> to an object or function of type <code class="computeroutput"><span class="identifier">T</span></code>.
      </p><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
  <span class="keyword">class</span> <span class="identifier">executor_binder</span>
  <span class="special">{</span>
  <span class="keyword">public</span><span class="special">:</span>
    <span class="comment">// types:</span>

    <span class="keyword">typedef</span> <span class="identifier">T</span> <span class="identifier">target_type</span><span class="special">;</span>
    <span class="keyword">typedef</span> <span class="identifier">Executor</span> <span class="identifier">executor_type</span><span class="special">;</span>

    <span class="comment">// construct / copy / destroy:</span>

    <span class="identifier">executor_binder</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">&amp;</span> <span class="identifier">ex</span><span class="special">);</span>
    <span class="identifier">executor_binder</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">executor_binder</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="special">=</span> <span class="keyword">default</span><span class="special">;</span>
    <span class="identifier">executor_binder</span><span class="special">(</span><span class="identifier">executor_binder</span><span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="special">=</span> <span class="keyword">default</span><span class="special">;</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;</span>
      <span class="identifier">executor_binder</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">,</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;&amp;</span> <span class="identifier">other</span><span class="special">);</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;</span>
      <span class="identifier">executor_binder</span><span class="special">(</span><span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">,</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;&amp;&amp;</span> <span class="identifier">other</span><span class="special">);</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;</span>
      <span class="identifier">executor_binder</span><span class="special">(</span><span class="identifier">executor_arg_t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">&amp;</span> <span class="identifier">ex</span><span class="special">,</span>
        <span class="keyword">const</span> <span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">,</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;&amp;</span> <span class="identifier">other</span><span class="special">);</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;</span>
      <span class="identifier">executor_binder</span><span class="special">(</span><span class="identifier">executor_arg_t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">&amp;</span> <span class="identifier">ex</span><span class="special">,</span>
        <span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">,</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;&amp;&amp;</span> <span class="identifier">other</span><span class="special">);</span>

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

    <span class="comment">// executor binder access:</span>

    <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">get</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">get</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="identifier">executor_type</span> <span class="identifier">get_executor</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="comment">// executor binder invocation:</span>

    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span>
      <span class="identifier">result_of_t</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&amp;(</span><span class="identifier">Args</span><span class="special">&amp;&amp;...)&gt;</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Args</span><span class="special">&amp;&amp;...</span> <span class="identifier">args</span><span class="special">);</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span>
      <span class="identifier">result_of_t</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;(</span><span class="identifier">Args</span><span class="special">&amp;&amp;...)&gt;</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Args</span><span class="special">&amp;&amp;...</span> <span class="identifier">args</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>

  <span class="keyword">private</span><span class="special">:</span>
    <span class="identifier">Executor</span> <span class="identifier">ex_</span><span class="special">;</span> <span class="comment">// <span class="emphasis"><em>exposition only</em></span></span>
    <span class="identifier">T</span> <span class="identifier">target_</span><span class="special">;</span> <span class="comment">// <span class="emphasis"><em>exposition only</em></span></span>
  <span class="special">};</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Signature</span><span class="special">&gt;</span>
    <span class="keyword">class</span> <span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">&gt;,</span> <span class="identifier">Signature</span><span class="special">&gt;;</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
    <span class="keyword">struct</span> <span class="identifier">associated_allocator</span><span class="special">&lt;</span><span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">&gt;,</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;;</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Executor1</span><span class="special">&gt;</span>
    <span class="keyword">struct</span> <span class="identifier">associated_executor</span><span class="special">&lt;</span><span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">&gt;,</span> <span class="identifier">Executor1</span><span class="special">&gt;;</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>
</pre><div class="section" title="12.15.1.&#160;executor_binder constructors"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__executor_binder__constructors"></a>12.15.1.&#160;<code class="literal">executor_binder</code> constructors</h4></div></div></div><pre class="programlisting"><span class="identifier">executor_binder</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">&amp;</span> <span class="identifier">ex</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Initializes <code class="computeroutput"><span class="identifier">ex_</span></code>
            with <code class="computeroutput"><span class="identifier">ex</span></code>. Initializes
            <code class="computeroutput"><span class="identifier">target_</span></code> by performing
            uses-executor construction, using the constructor argument <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">t</span><span class="special">)</span></code>
            and the executor <code class="computeroutput"><span class="identifier">ex_</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;</span>
  <span class="identifier">executor_binder</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">,</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;&amp;</span> <span class="identifier">other</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Requires:</em></span> If <code class="computeroutput"><span class="identifier">U</span></code>
            is not convertible to <code class="computeroutput"><span class="identifier">T</span></code>,
            or if <code class="computeroutput"><span class="identifier">OtherExecutor</span></code> is
            not convertible to <code class="computeroutput"><span class="identifier">Executor</span></code>,
            the program is ill-formed.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Initializes <code class="computeroutput"><span class="identifier">ex_</span></code>
            with <code class="computeroutput"><span class="identifier">other</span><span class="special">.</span><span class="identifier">get_executor</span><span class="special">()</span></code>.
            Initializes <code class="computeroutput"><span class="identifier">target_</span></code> by
            performing uses-executor construction, using the constructor argument
            <code class="computeroutput"><span class="identifier">other</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span></code>
            and the executor <code class="computeroutput"><span class="identifier">ex_</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;</span>
  <span class="identifier">executor_binder</span><span class="special">(</span><span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">,</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;&amp;&amp;</span> <span class="identifier">other</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Requires:</em></span> If <code class="computeroutput"><span class="identifier">U</span></code>
            is not convertible to <code class="computeroutput"><span class="identifier">T</span></code>,
            or if <code class="computeroutput"><span class="identifier">OtherExecutor</span></code> is
            not convertible to <code class="computeroutput"><span class="identifier">Executor</span></code>,
            the program is ill-formed.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Initializes <code class="computeroutput"><span class="identifier">ex_</span></code>
            with <code class="computeroutput"><span class="identifier">other</span><span class="special">.</span><span class="identifier">get_executor</span><span class="special">()</span></code>.
            Initializes <code class="computeroutput"><span class="identifier">target_</span></code> by
            performing uses-executor construction, using the constructor argument
            <code class="computeroutput"><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">get</span><span class="special">())</span></code>
            and the executor <code class="computeroutput"><span class="identifier">ex_</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;</span>
  <span class="identifier">executor_binder</span><span class="special">(</span><span class="identifier">executor_arg_t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">&amp;</span> <span class="identifier">ex</span><span class="special">,</span>
    <span class="keyword">const</span> <span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">,</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;&amp;</span> <span class="identifier">other</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Requires:</em></span> If <code class="computeroutput"><span class="identifier">U</span></code>
            is not convertible to <code class="computeroutput"><span class="identifier">T</span></code>
            the program is ill-formed.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Initializes <code class="computeroutput"><span class="identifier">ex_</span></code>
            with <code class="computeroutput"><span class="identifier">ex</span></code>. Initializes
            <code class="computeroutput"><span class="identifier">target_</span></code> by performing
            uses-executor construction, using the constructor argument <code class="computeroutput"><span class="identifier">other</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span></code>
            and the executor <code class="computeroutput"><span class="identifier">ex_</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;</span>
  <span class="identifier">executor_binder</span><span class="special">(</span><span class="identifier">executor_arg_t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">&amp;</span> <span class="identifier">ex</span><span class="special">,</span>
    <span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">,</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;&amp;&amp;</span> <span class="identifier">other</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Requires:</em></span> <code class="computeroutput"><span class="identifier">U</span></code>
            is <code class="computeroutput"><span class="identifier">T</span></code> or convertible to
            <code class="computeroutput"><span class="identifier">T</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Initializes <code class="computeroutput"><span class="identifier">ex_</span></code>
            with <code class="computeroutput"><span class="identifier">ex</span></code>. Initializes
            <code class="computeroutput"><span class="identifier">target_</span></code> by performing
            uses-executor construction, using the constructor argument <code class="computeroutput"><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">get</span><span class="special">())</span></code>
            and the executor <code class="computeroutput"><span class="identifier">ex_</span></code>.
          </p></blockquote></div></div><div class="section" title="12.15.2.&#160;executor_binder access"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__executor_binder__access"></a>12.15.2.&#160;<code class="literal">executor_binder</code> access</h4></div></div></div><pre class="programlisting"><span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">get</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">get</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">target_</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">executor_type</span> <span class="identifier">get_executor</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">executor_</span></code>.
          </p></blockquote></div></div><div class="section" title="12.15.3.&#160;executor_binder invocation"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__executor_binder__invocation"></a>12.15.3.&#160;<code class="literal">executor_binder</code> invocation</h4></div></div></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span>
  <span class="identifier">result_of_t</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&amp;(</span><span class="identifier">Args</span><span class="special">&amp;&amp;...)&gt;</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Args</span><span class="special">&amp;&amp;...</span> <span class="identifier">args</span><span class="special">);</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span>
  <span class="identifier">result_of_t</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;(</span><span class="identifier">Args</span><span class="special">&amp;&amp;...)&gt;</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Args</span><span class="special">&amp;&amp;...</span> <span class="identifier">args</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="literal"><span class="emphasis"><em>INVOKE</em></span></code><code class="computeroutput"><span class="special">(</span><span class="identifier">get</span><span class="special">(),</span> <span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Args</span><span class="special">&gt;(</span><span class="identifier">args</span><span class="special">)</span>...<span class="special">)</span></code>
            (C++Std [func.require]).
          </p></blockquote></div></div><div class="section" title="12.15.4.&#160;Class template partial specialization async_result"><div class="titlepage"><div><div><h4 class="title"><a name="classes.class_template_partial_specialization___async_result_"></a>12.15.4.&#160;Class template partial specialization <code class="literal">async_result</code></h4></div></div></div><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Signature</span><span class="special">&gt;</span>
  <span class="keyword">class</span> <span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">&gt;,</span> <span class="identifier">Signature</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">executor_binder</span><span class="special">&lt;</span>
      <span class="keyword">typename</span> <span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Signature</span><span class="special">&gt;::</span><span class="identifier">completion_handler_type</span><span class="special">,</span>
        <span class="identifier">Executor</span><span class="special">&gt;</span> <span class="identifier">completion_handler_type</span><span class="special">;</span>
    <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Signature</span><span class="special">&gt;::</span><span class="identifier">return_type</span> <span class="identifier">return_type</span><span class="special">;</span>

    <span class="keyword">explicit</span> <span class="identifier">async_result</span><span class="special">(</span><span class="identifier">completion_handler_type</span><span class="special">&amp;</span> <span class="identifier">h</span><span class="special">);</span>
    <span class="identifier">async_result</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">async_result</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
    <span class="identifier">async_result</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">async_result</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>

    <span class="identifier">return_type</span> <span class="identifier">get</span><span class="special">();</span>

  <span class="keyword">private</span><span class="special">:</span>
    <span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Signature</span><span class="special">&gt;</span> <span class="identifier">target_</span><span class="special">;</span> <span class="comment">// <span class="emphasis"><em>exposition only</em></span></span>
  <span class="special">};</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>

<span class="keyword">explicit</span> <span class="identifier">async_result</span><span class="special">(</span><span class="identifier">completion_handler_type</span><span class="special">&amp;</span> <span class="identifier">h</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Initializes <code class="computeroutput"><span class="identifier">target_</span></code>
            as <code class="computeroutput"><span class="identifier">target_</span><span class="special">(</span><span class="identifier">h</span><span class="special">.</span><span class="identifier">get</span><span class="special">())</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">return_type</span> <span class="identifier">get</span><span class="special">();</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">target_</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span></code>.
          </p></blockquote></div></div><div class="section" title="12.15.5.&#160;Class template partial specialization associated_allocator"><div class="titlepage"><div><div><h4 class="title"><a name="classes.class_template_partial_specialization___associated_allocator_"></a>12.15.5.&#160;Class template partial specialization <code class="literal">associated_allocator</code></h4></div></div></div><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
    <span class="keyword">struct</span> <span class="identifier">associated_allocator</span><span class="special">&lt;</span><span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">&gt;,</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
  <span class="special">{</span>
    <span class="keyword">typedef</span> <span class="identifier">associated_allocator_t</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span> <span class="identifier">type</span><span class="special">;</span>

    <span class="keyword">static</span> <span class="identifier">type</span> <span class="identifier">get</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">&gt;&amp;</span> <span class="identifier">b</span><span class="special">,</span>
                    <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">ProtoAllocator</span><span class="special">())</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="special">};</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>

<span class="keyword">static</span> <span class="identifier">type</span> <span class="identifier">get</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">&gt;&amp;</span> <span class="identifier">b</span><span class="special">,</span>
                <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">ProtoAllocator</span><span class="special">())</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">associated_allocator</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;::</span><span class="identifier">get</span><span class="special">(</span><span class="identifier">b</span><span class="special">.</span><span class="identifier">get</span><span class="special">(),</span> <span class="identifier">a</span><span class="special">)</span></code>.
          </p></blockquote></div></div><div class="section" title="12.15.6.&#160;Class template partial specialization associated_executor"><div class="titlepage"><div><div><h4 class="title"><a name="classes.class_template_partial_specialization___associated_executor_"></a>12.15.6.&#160;Class template partial specialization <code class="literal">associated_executor</code></h4></div></div></div><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Executor1</span><span class="special">&gt;</span>
    <span class="keyword">struct</span> <span class="identifier">associated_executor</span><span class="special">&lt;</span><span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">&gt;,</span> <span class="identifier">Executor1</span><span class="special">&gt;</span>
  <span class="special">{</span>
    <span class="keyword">typedef</span> <span class="identifier">Executor</span> <span class="identifier">type</span><span class="special">;</span>

    <span class="keyword">static</span> <span class="identifier">type</span> <span class="identifier">get</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">&gt;&amp;</span> <span class="identifier">b</span><span class="special">,</span>
                    <span class="keyword">const</span> <span class="identifier">Executor1</span><span class="special">&amp;</span> <span class="identifier">e</span> <span class="special">=</span> <span class="identifier">Executor1</span><span class="special">())</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="special">};</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>

<span class="keyword">static</span> <span class="identifier">type</span> <span class="identifier">get</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">&gt;&amp;</span> <span class="identifier">b</span><span class="special">,</span>
                <span class="keyword">const</span> <span class="identifier">Executor1</span><span class="special">&amp;</span> <span class="identifier">e</span> <span class="special">=</span> <span class="identifier">Executor1</span><span class="special">())</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">b</span><span class="special">.</span><span class="identifier">get_executor</span><span class="special">()</span></code>.
          </p></blockquote></div></div></div><div class="section" title="12.16.&#160;Function bind_executor"><div class="titlepage"><div><div><h3 class="title"><a name="functions.bind_executor"></a>12.16.&#160;Function <code class="literal">bind_executor</code></h3></div></div></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
  <span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">decay_t</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;,</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
    <span class="identifier">bind_executor</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">&amp;</span> <span class="identifier">ex</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&amp;&amp;</span> <span class="identifier">t</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">decay_t</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;,</span> <span class="identifier">Executor</span><span class="special">&gt;(</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;(</span><span class="identifier">t</span><span class="special">),</span> <span class="identifier">ex</span><span class="special">)</span></code>.
        </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Remarks:</em></span> This function shall not participate in overload
          resolution unless <code class="computeroutput"><span class="identifier">is_executor</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;::</span><span class="identifier">value</span></code>
          is <code class="computeroutput"><span class="keyword">true</span></code>.
        </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ExecutionContext</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
  <span class="identifier">executor_binder</span><span class="special">&lt;</span><span class="identifier">decay_t</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;,</span> <span class="keyword">typename</span> <span class="identifier">ExecutionContext</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&gt;</span>
    <span class="identifier">bind_executor</span><span class="special">(</span><span class="identifier">ExecutionContext</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&amp;&amp;</span> <span class="identifier">t</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">bind_executor</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">.</span><span class="identifier">get_executor</span><span class="special">(),</span> <span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;(</span><span class="identifier">t</span><span class="special">))</span></code>.
        </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Remarks:</em></span> This function shall not participate in overload
          resolution unless <code class="computeroutput"><span class="identifier">is_convertible</span><span class="special">&lt;</span><span class="identifier">ExecutionContext</span><span class="special">&amp;,</span> <span class="identifier">execution_context</span><span class="special">&amp;&gt;::</span><span class="identifier">value</span></code>
          is <code class="computeroutput"><span class="keyword">true</span></code>.
        </p></blockquote></div></div><div class="section" title="12.17.&#160;Class template executor_work_guard"><div class="titlepage"><div><div><h3 class="title"><a name="classes.executor_work_guard"></a>12.17.&#160;Class template <code class="literal">executor_work_guard</code></h3></div></div></div><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
  <span class="keyword">class</span> <span class="identifier">executor_work_guard</span>
  <span class="special">{</span>
  <span class="keyword">public</span><span class="special">:</span>
    <span class="comment">// types:</span>

    <span class="keyword">typedef</span> <span class="identifier">Executor</span> <span class="identifier">executor_type</span><span class="special">;</span>

    <span class="comment">// construct / copy / destroy:</span>

    <span class="keyword">explicit</span> <span class="identifier">executor_work_guard</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">ex</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="identifier">executor_work_guard</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">executor_work_guard</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="identifier">executor_work_guard</span><span class="special">(</span><span class="identifier">executor_work_guard</span><span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>

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

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

    <span class="comment">// executor work guard observers:</span>

    <span class="identifier">executor_type</span> <span class="identifier">get_executor</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">bool</span> <span class="identifier">owns_work</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="comment">// executor work guard modifiers:</span>

    <span class="keyword">void</span> <span class="identifier">reset</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>

  <span class="keyword">private</span><span class="special">:</span>
    <span class="identifier">Executor</span> <span class="identifier">ex_</span><span class="special">;</span> <span class="comment">// <span class="emphasis"><em>exposition only</em></span></span>
    <span class="keyword">bool</span> <span class="identifier">owns_</span><span class="special">;</span> <span class="comment">// <span class="emphasis"><em>exposition only</em></span></span>
  <span class="special">};</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>
</pre><div class="section" title="12.17.1.&#160;executor_work_guard members"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__executor_work_guard__members"></a>12.17.1.&#160;<code class="literal">executor_work_guard</code> members</h4></div></div></div><pre class="programlisting"><span class="keyword">explicit</span> <span class="identifier">executor_work_guard</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">ex</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Initializes <code class="computeroutput"><span class="identifier">ex_</span></code>
            with <code class="computeroutput"><span class="identifier">ex</span></code>, and then performs
            <code class="computeroutput"><span class="identifier">ex_</span><span class="special">.</span><span class="identifier">on_work_started</span><span class="special">()</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="identifier">ex</span>
            <span class="special">==</span> <span class="identifier">ex_</span></code>
            and <code class="computeroutput"><span class="identifier">owns_</span> <span class="special">==</span>
            <span class="keyword">true</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">executor_work_guard</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">executor_work_guard</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Initializes <code class="computeroutput"><span class="identifier">ex_</span></code>
            with <code class="computeroutput"><span class="identifier">other</span><span class="special">.</span><span class="identifier">ex_</span></code>. If <code class="computeroutput"><span class="identifier">other</span><span class="special">.</span><span class="identifier">owns_</span> <span class="special">==</span> <span class="keyword">true</span></code>,
            performs <code class="computeroutput"><span class="identifier">ex_</span><span class="special">.</span><span class="identifier">on_work_started</span><span class="special">()</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="identifier">ex_</span>
            <span class="special">==</span> <span class="identifier">other</span><span class="special">.</span><span class="identifier">ex_</span></code>
            and <code class="computeroutput"><span class="identifier">owns_</span> <span class="special">==</span>
            <span class="identifier">other</span><span class="special">.</span><span class="identifier">owns_</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">executor_work_guard</span><span class="special">(</span><span class="identifier">executor_work_guard</span><span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Initializes <code class="computeroutput"><span class="identifier">ex_</span></code>
            with <code class="computeroutput"><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">ex_</span><span class="special">)</span></code>
            and <code class="computeroutput"><span class="identifier">owns_</span></code> with <code class="computeroutput"><span class="identifier">other</span><span class="special">.</span><span class="identifier">owns_</span></code>, and sets <code class="computeroutput"><span class="identifier">other</span><span class="special">.</span><span class="identifier">owns_</span></code>
            to <code class="computeroutput"><span class="keyword">false</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="special">~</span><span class="identifier">executor_work_guard</span><span class="special">();</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> If <code class="computeroutput"><span class="identifier">owns_</span></code>
            is <code class="computeroutput"><span class="keyword">true</span></code>, performs <code class="computeroutput"><span class="identifier">ex_</span><span class="special">.</span><span class="identifier">on_work_finished</span><span class="special">()</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">executor_type</span> <span class="identifier">get_executor</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">ex_</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">owns_work</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">owns_</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">reset</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> If <code class="computeroutput"><span class="identifier">owns_</span></code>
            is <code class="computeroutput"><span class="keyword">true</span></code>, performs <code class="computeroutput"><span class="identifier">ex_</span><span class="special">.</span><span class="identifier">on_work_finished</span><span class="special">()</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="identifier">owns_</span>
            <span class="special">==</span> <span class="keyword">false</span></code>.
          </p></blockquote></div></div></div><div class="section" title="12.18.&#160;Function make_work_guard"><div class="titlepage"><div><div><h3 class="title"><a name="functions.make_work_guard"></a>12.18.&#160;Function <code class="literal">make_work_guard</code></h3></div></div></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
  <span class="identifier">executor_work_guard</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;</span>
    <span class="identifier">make_work_guard</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">&amp;</span> <span class="identifier">ex</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">executor_work_guard</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;(</span><span class="identifier">ex</span><span class="special">)</span></code>.
        </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Remarks:</em></span> This function shall not participate in overload
          resolution unless <code class="computeroutput"><span class="identifier">is_executor</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;::</span><span class="identifier">value</span></code>
          is <code class="computeroutput"><span class="keyword">true</span></code>.
        </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ExecutionContext</span><span class="special">&gt;</span>
  <span class="identifier">executor_work_guard</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">ExecutionContext</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&gt;</span>
    <span class="identifier">make_work_guard</span><span class="special">(</span><span class="identifier">ExecutionContext</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">make_work_guard</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">.</span><span class="identifier">get_executor</span><span class="special">())</span></code>.
        </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Remarks:</em></span> This function shall not participate in overload
          resolution unless <code class="computeroutput"><span class="identifier">is_convertible</span><span class="special">&lt;</span><span class="identifier">ExecutionContext</span><span class="special">&amp;,</span> <span class="identifier">execution_context</span><span class="special">&amp;&gt;::</span><span class="identifier">value</span></code>
          is <code class="computeroutput"><span class="keyword">true</span></code>.
        </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
  <span class="identifier">executor_work_guard</span><span class="special">&lt;</span><span class="identifier">associated_executor_t</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&gt;</span>
    <span class="identifier">make_work_guard</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">t</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">make_work_guard</span><span class="special">(</span><span class="identifier">get_associated_executor</span><span class="special">(</span><span class="identifier">t</span><span class="special">))</span></code>.
        </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Remarks:</em></span> This function shall not participate in overload
          resolution unless <code class="computeroutput"><span class="identifier">is_executor</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value</span></code>
          is <code class="computeroutput"><span class="keyword">false</span></code> and <code class="computeroutput"><span class="identifier">is_convertible</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&amp;,</span> <span class="identifier">execution_context</span><span class="special">&amp;&gt;::</span><span class="identifier">value</span></code> is <code class="computeroutput"><span class="keyword">false</span></code>.
        </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span>
  <span class="keyword">auto</span> <span class="identifier">make_work_guard</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">t</span><span class="special">,</span> <span class="identifier">U</span><span class="special">&amp;&amp;</span> <span class="identifier">u</span><span class="special">)</span>
    <span class="special">-&gt;</span> <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">make_work_guard</span><span class="special">(</span><span class="identifier">get_associated_executor</span><span class="special">(</span><span class="identifier">t</span><span class="special">,</span> <span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;(</span><span class="identifier">u</span><span class="special">))));</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">make_work_guard</span><span class="special">(</span><span class="identifier">get_associated_executor</span><span class="special">(</span><span class="identifier">t</span><span class="special">,</span>
          <span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;(</span><span class="identifier">u</span><span class="special">)))</span></code>.
        </p></blockquote></div></div><div class="section" title="12.19.&#160;Class system_executor"><div class="titlepage"><div><div><h3 class="title"><a name="classes.system_executor"></a>12.19.&#160;Class <code class="literal">system_executor</code></h3></div></div></div><p>
        Class <code class="computeroutput"><span class="identifier">system_executor</span></code> represents
        a set of rules where function objects are permitted to execute on any thread.
      </p><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">class</span> <span class="identifier">system_executor</span>
  <span class="special">{</span>
  <span class="keyword">public</span><span class="special">:</span>
    <span class="comment">// constructors:</span>

    <span class="identifier">system_executor</span><span class="special">()</span> <span class="special">{}</span>

    <span class="comment">// executor operations:</span>

    <span class="identifier">system_context</span><span class="special">&amp;</span> <span class="identifier">context</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="keyword">void</span> <span class="identifier">on_work_started</span><span class="special">()</span> <span class="keyword">noexcept</span> <span class="special">{}</span>
    <span class="keyword">void</span> <span class="identifier">on_work_finished</span><span class="special">()</span> <span class="keyword">noexcept</span> <span class="special">{}</span>

    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
      <span class="keyword">void</span> <span class="identifier">dispatch</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
      <span class="keyword">void</span> <span class="identifier">post</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
      <span class="keyword">void</span> <span class="identifier">defer</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
  <span class="special">};</span>

  <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">system_executor</span><span class="special">&amp;,</span> <span class="keyword">const</span> <span class="identifier">system_executor</span><span class="special">&amp;)</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="keyword">const</span> <span class="identifier">system_executor</span><span class="special">&amp;,</span> <span class="keyword">const</span> <span class="identifier">system_executor</span><span class="special">&amp;)</span> <span class="keyword">noexcept</span><span class="special">;</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>
</pre><p>
        Class <code class="computeroutput"><span class="identifier">system_executor</span></code> satisfies
        the <code class="computeroutput"><span class="identifier">Destructible</span></code> (C++Std
        [destructible]), <code class="computeroutput"><span class="identifier">DefaultConstructible</span></code>
        (C++Std [defaultconstructible]), and <a class="link" href="#requirements.executor" title="12.3.3.&#160;Executor requirements"><code class="computeroutput"><span class="identifier">Executor</span></code></a> type requirements.
      </p><p>
        To satisfy the <code class="computeroutput"><span class="identifier">Executor</span></code> requirements
        for the <code class="computeroutput"><span class="identifier">post</span></code> and <code class="computeroutput"><span class="identifier">defer</span></code> member functions, the system executor
        may create <code class="computeroutput"><span class="identifier">thread</span></code> objects
        to run the submitted function objects. These <code class="computeroutput"><span class="identifier">thread</span></code>
        objects are collectively referred to as <span class="emphasis"><em>system threads</em></span>.
      </p><div class="section" title="12.19.1.&#160;system_executor operations"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__system_executor__operations"></a>12.19.1.&#160;<code class="literal">system_executor</code> operations</h4></div></div></div><pre class="programlisting"><span class="identifier">system_context</span><span class="special">&amp;</span> <span class="identifier">context</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> A reference to an object with static storage
            duration. All calls to this function return references to the same object.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
  <span class="keyword">void</span> <span class="identifier">dispatch</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Equivalent to <code class="literal"><span class="emphasis"><em>DECAY_COPY</em></span></code><code class="computeroutput"><span class="special">(</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Func</span><span class="special">&gt;(</span><span class="identifier">f</span><span class="special">))()</span></code> (C++Std [thread.decaycopy]).
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
  <span class="keyword">void</span> <span class="identifier">post</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
  <span class="keyword">void</span> <span class="identifier">defer</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> If <code class="computeroutput"><span class="identifier">context</span><span class="special">().</span><span class="identifier">stopped</span><span class="special">()</span> <span class="special">==</span> <span class="keyword">false</span></code>, creates an object <code class="computeroutput"><span class="identifier">f1</span></code> initialized with <code class="literal"><span class="emphasis"><em>DECAY_COPY</em></span></code><code class="computeroutput"><span class="special">(</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Func</span><span class="special">&gt;(</span><span class="identifier">f</span><span class="special">))</span></code>, and calls <code class="computeroutput"><span class="identifier">f1</span></code>
            as if in a thread of execution represented by a <code class="computeroutput"><span class="identifier">thread</span></code>
            object. Any exception propagated from the execution of <code class="literal"><span class="emphasis"><em>DECAY_COPY</em></span></code><code class="computeroutput"><span class="special">(</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Func</span><span class="special">&gt;(</span><span class="identifier">f</span><span class="special">))()</span></code> results in a call to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">terminate</span></code>.
          </p></blockquote></div></div><div class="section" title="12.19.2.&#160;system_executor comparisons"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__system_executor__comparisons"></a>12.19.2.&#160;<code class="literal">system_executor</code> comparisons</h4></div></div></div><pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">system_executor</span><span class="special">&amp;,</span> <span class="keyword">const</span> <span class="identifier">system_executor</span><span class="special">&amp;)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="keyword">true</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="keyword">const</span> <span class="identifier">system_executor</span><span class="special">&amp;,</span> <span class="keyword">const</span> <span class="identifier">system_executor</span><span class="special">&amp;)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="keyword">false</span></code>.
          </p></blockquote></div></div></div><div class="section" title="12.20.&#160;Class system_context"><div class="titlepage"><div><div><h3 class="title"><a name="classes.system_context"></a>12.20.&#160;Class <code class="literal">system_context</code></h3></div></div></div><p>
        Class <code class="computeroutput"><span class="identifier">system_context</span></code> implements
        the execution context associated with <code class="computeroutput"><span class="identifier">system_executor</span></code>
        objects.
      </p><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">class</span> <span class="identifier">system_context</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">execution_context</span>
  <span class="special">{</span>
  <span class="keyword">public</span><span class="special">:</span>
    <span class="comment">// types:</span>

    <span class="keyword">typedef</span> <a class="link" href="#classes.system_executor" title="12.19.&#160;Class system_executor">system_executor</a> <span class="identifier">executor_type</span><span class="special">;</span>

    <span class="comment">// construct / copy / destroy:</span>

    <span class="identifier">system_context</span><span class="special">()</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
    <span class="identifier">system_context</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">system_context</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
    <span class="identifier">system_context</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">system_context</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
    <span class="special">~</span><span class="identifier">system_context</span><span class="special">();</span>

    <span class="comment">// system_context operations:</span>

    <span class="identifier">executor_type</span> <span class="identifier">get_executor</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="keyword">void</span> <span class="identifier">stop</span><span class="special">();</span>
    <span class="keyword">bool</span> <span class="identifier">stopped</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">void</span> <span class="identifier">join</span><span class="special">();</span>
  <span class="special">};</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>
</pre><p>
        The class <code class="computeroutput"><span class="identifier">system_context</span></code>
        satisfies the <a class="link" href="#requirements.execution_context" title="12.3.2.&#160;Execution context requirements"><code class="computeroutput"><span class="identifier">ExecutionContext</span></code></a> type requirements.
      </p><p>
        The <code class="computeroutput"><span class="identifier">system_context</span></code> member
        functions <code class="computeroutput"><span class="identifier">get_executor</span></code>,
        <code class="computeroutput"><span class="identifier">stop</span></code>, and <code class="computeroutput"><span class="identifier">stopped</span></code>,
        and the <code class="computeroutput"><span class="identifier">system_executor</span></code> copy
        constructors, member functions and comparison operators, do not introduce
        data races as a result of concurrent calls to those functions from different
        threads of execution.
      </p><pre class="programlisting"><span class="special">~</span><span class="identifier">system_context</span><span class="special">();</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Effects:</em></span> Performs <code class="computeroutput"><span class="identifier">stop</span><span class="special">()</span></code> followed by <code class="computeroutput"><span class="identifier">join</span><span class="special">()</span></code>.
        </p></blockquote></div><pre class="programlisting"><span class="identifier">executor_type</span> <span class="identifier">get_executor</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">system_executor</span><span class="special">()</span></code>.
        </p></blockquote></div><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">stop</span><span class="special">();</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Effects:</em></span> Signals all system threads to exit as soon
          as possible. If a system thread is currently executing a function object,
          the thread will exit only after completion of that function object. Returns
          without waiting for the system threads to complete.
        </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="identifier">stopped</span><span class="special">()</span> <span class="special">==</span> <span class="keyword">true</span></code>.
        </p></blockquote></div><pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">stopped</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="keyword">true</span></code>
          if the <code class="computeroutput"><span class="identifier">system_context</span></code> has
          been stopped by a prior call to <code class="computeroutput"><span class="identifier">stop</span></code>.
        </p></blockquote></div><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">join</span><span class="special">();</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Effects:</em></span> Blocks the calling thread (C++Std [defns.block])
          until all system threads have completed.
        </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Synchronization:</em></span> The completion of each system thread
          synchronizes with (C++Std [intro.multithread]) the corresponding successful
          <code class="computeroutput"><span class="identifier">join</span><span class="special">()</span></code>
          return.
        </p></blockquote></div></div><div class="section" title="12.21.&#160;Class bad_executor"><div class="titlepage"><div><div><h3 class="title"><a name="classes.bad_executor"></a>12.21.&#160;Class <code class="literal">bad_executor</code></h3></div></div></div><p>
        An exception of type <code class="computeroutput"><span class="identifier">bad_executor</span></code>
        is thrown by <code class="computeroutput"><span class="identifier">executor</span></code> member
        functions <code class="computeroutput"><span class="identifier">dispatch</span></code>, <code class="computeroutput"><span class="identifier">post</span></code>, and <code class="computeroutput"><span class="identifier">defer</span></code>
        when the executor object has no target.
      </p><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">class</span> <span class="identifier">bad_executor</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">exception</span>
  <span class="special">{</span>
  <span class="keyword">public</span><span class="special">:</span>
    <span class="comment">// constructor:</span>
    <span class="identifier">bad_executor</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="special">};</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>

<span class="identifier">bad_executor</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Effects:</em></span> constructs a <code class="computeroutput"><span class="identifier">bad_executor</span></code>
          object.
        </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="identifier">what</span><span class="special">()</span></code> returns an implementation-defined NTBS.
        </p></blockquote></div></div><div class="section" title="12.22.&#160;Class executor"><div class="titlepage"><div><div><h3 class="title"><a name="classes.executor"></a>12.22.&#160;Class <code class="literal">executor</code></h3></div></div></div><p>
        The <code class="computeroutput"><span class="identifier">executor</span></code> class provides
        a polymorphic wrapper for types that satisfy the <a class="link" href="#requirements.executor" title="12.3.3.&#160;Executor requirements">Executor
        requirements</a>.
      </p><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">class</span> <span class="identifier">executor</span>
  <span class="special">{</span>
  <span class="keyword">public</span><span class="special">:</span>
    <span class="comment">// construct / copy / destroy:</span>

    <span class="identifier">executor</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="identifier">executor</span><span class="special">(</span><span class="identifier">nullptr_t</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="identifier">executor</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="identifier">executor</span><span class="special">(</span><span class="identifier">executor</span><span class="special">&amp;&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span> <span class="identifier">executor</span><span class="special">(</span><span class="identifier">Executor</span> <span class="identifier">e</span><span class="special">);</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
      <span class="identifier">executor</span><span class="special">(</span><span class="identifier">allocator_arg_t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">Executor</span> <span class="identifier">e</span><span class="special">);</span>

    <span class="identifier">executor</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="identifier">executor</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">executor</span><span class="special">&amp;&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="identifier">executor</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">nullptr_t</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">Executor</span> <span class="identifier">e</span><span class="special">);</span>

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

    <span class="comment">// executor modifiers:</span>

    <span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
      <span class="keyword">void</span> <span class="identifier">assign</span><span class="special">(</span><span class="identifier">Executor</span> <span class="identifier">e</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>

    <span class="comment">// executor operations:</span>

    <span class="identifier">execution_context</span><span class="special">&amp;</span> <span class="identifier">context</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="keyword">void</span> <span class="identifier">on_work_started</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">void</span> <span class="identifier">on_work_finished</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
      <span class="keyword">void</span> <span class="identifier">dispatch</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
      <span class="keyword">void</span> <span class="identifier">post</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
      <span class="keyword">void</span> <span class="identifier">defer</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>

    <span class="comment">// executor capacity:</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="keyword">noexcept</span><span class="special">;</span>

    <span class="comment">// executor target access:</span>

    <span class="keyword">const</span> <span class="identifier">type_info</span><span class="special">&amp;</span> <span class="identifier">target_type</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span> <span class="identifier">Executor</span><span class="special">*</span> <span class="identifier">target</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">*</span> <span class="identifier">target</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="special">};</span>

  <span class="keyword">template</span><span class="special">&lt;&gt;</span> <span class="keyword">struct</span> <span class="identifier">is_executor</span><span class="special">&lt;</span><span class="identifier">executor</span><span class="special">&gt;</span> <span class="special">:</span> <span class="identifier">true_type</span> <span class="special">{};</span>

  <span class="comment">// executor comparisons:</span>

  <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">,</span> <span class="identifier">nullptr_t</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="identifier">nullptr_t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">,</span> <span class="identifier">nullptr_t</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="identifier">nullptr_t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>

  <span class="comment">// executor specialized algorithms:</span>

  <span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Allocator</span><span class="special">&gt;</span>
    <span class="keyword">struct</span> <span class="identifier">uses_allocator</span><span class="special">&lt;</span><span class="identifier">experimental</span><span class="special">::</span>concurrency_v2<span class="special">::</span><span class="identifier">executor</span><span class="special">,</span> <span class="identifier">Allocator</span><span class="special">&gt;</span>
      <span class="special">:</span> <span class="identifier">true_type</span> <span class="special">{};</span>

<span class="special">}</span> <span class="comment">// namespace std</span>
</pre><p>
        Class <code class="computeroutput"><span class="identifier">executor</span></code> meets the
        requirements of <a class="link" href="#requirements.executor" title="12.3.3.&#160;Executor requirements"><code class="computeroutput"><span class="identifier">Executor</span></code></a>,
        <code class="computeroutput"><span class="identifier">DefaultConstructible</span></code> (C++Std
        [defaultconstructible]), and <code class="computeroutput"><span class="identifier">CopyAssignable</span></code>
        (C++Std [copyassignable]).
      </p><p>
        [<span class="emphasis"><em>Note:</em></span> To meet the <code class="computeroutput"><span class="keyword">noexcept</span></code>
        requirements for executor copy constructors and move constructors, implementations
        may share a target between two or more <code class="computeroutput"><span class="identifier">executor</span></code>
        objects. &#8212;<span class="emphasis"><em>end note</em></span>]
      </p><p>
        The <span class="emphasis"><em>target</em></span> is the executor object that is held by the
        wrapper.
      </p><div class="section" title="12.22.1.&#160;executor constructors"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__executor__constructors"></a>12.22.1.&#160;<code class="literal">executor</code> constructors</h4></div></div></div><pre class="programlisting"><span class="identifier">executor</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="special">!*</span><span class="keyword">this</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">executor</span><span class="special">(</span><span class="identifier">nullptr_t</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="special">!*</span><span class="keyword">this</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">executor</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="special">!*</span><span class="keyword">this</span></code> if <code class="computeroutput"><span class="special">!</span><span class="identifier">e</span></code>; otherwise, <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> targets <code class="computeroutput"><span class="identifier">e</span><span class="special">.</span><span class="identifier">target</span><span class="special">()</span></code> or a copy of <code class="computeroutput"><span class="identifier">e</span><span class="special">.</span><span class="identifier">target</span><span class="special">()</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">executor</span><span class="special">(</span><span class="identifier">executor</span><span class="special">&amp;&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> If <code class="computeroutput"><span class="special">!</span><span class="identifier">e</span></code>, <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> has no target; otherwise, moves
            <code class="computeroutput"><span class="identifier">e</span><span class="special">.</span><span class="identifier">target</span><span class="special">()</span></code>
            or move-constructs the target of <code class="computeroutput"><span class="identifier">e</span></code>
            into the target of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>,
            leaving <code class="computeroutput"><span class="identifier">e</span></code> in a valid
            state with an unspecified value.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span> <span class="identifier">executor</span><span class="special">(</span><span class="identifier">Executor</span> <span class="identifier">e</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> targets a copy of <code class="computeroutput"><span class="identifier">e</span></code>
            initialized with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">e</span><span class="special">)</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
  <span class="identifier">executor</span><span class="special">(</span><span class="identifier">allocator_arg_t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">Executor</span> <span class="identifier">e</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> targets a copy of <code class="computeroutput"><span class="identifier">e</span></code>
            initialized with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">e</span><span class="special">)</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            A copy of the allocator argument is used to allocate memory, if necessary,
            for the internal data structures of the constructed <code class="computeroutput"><span class="identifier">executor</span></code>
            object.
          </p></blockquote></div></div><div class="section" title="12.22.2.&#160;executor assignment"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__executor__assignment"></a>12.22.2.&#160;<code class="literal">executor</code> assignment</h4></div></div></div><pre class="programlisting"><span class="identifier">executor</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> <code class="computeroutput"><span class="identifier">executor</span><span class="special">(</span><span class="identifier">e</span><span class="special">).</span><span class="identifier">swap</span><span class="special">(*</span><span class="keyword">this</span><span class="special">)</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">executor</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">executor</span><span class="special">&amp;&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Replaces the target of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> with the target of <code class="computeroutput"><span class="identifier">e</span></code>, leaving <code class="computeroutput"><span class="identifier">e</span></code>
            in a valid state with an unspecified value.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">executor</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">nullptr_t</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> <code class="computeroutput"><span class="identifier">executor</span><span class="special">(</span><span class="keyword">nullptr</span><span class="special">).</span><span class="identifier">swap</span><span class="special">(*</span><span class="keyword">this</span><span class="special">)</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">Executor</span> <span class="identifier">e</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> <code class="computeroutput"><span class="identifier">executor</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">e</span><span class="special">)).</span><span class="identifier">swap</span><span class="special">(*</span><span class="keyword">this</span><span class="special">)</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
          </p></blockquote></div></div><div class="section" title="12.22.3.&#160;executor destructor"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__executor__destructor"></a>12.22.3.&#160;<code class="literal">executor</code> destructor</h4></div></div></div><pre class="programlisting"><span class="special">~</span><span class="identifier">executor</span><span class="special">();</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> If <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span> <span class="special">!=</span> <span class="keyword">nullptr</span></code>, releases shared ownership of,
            or destroys, the target of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
          </p></blockquote></div></div><div class="section" title="12.22.4.&#160;executor modifiers"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__executor__modifiers"></a>12.22.4.&#160;<code class="literal">executor</code> modifiers</h4></div></div></div><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Interchanges the targets of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
            and <code class="computeroutput"><span class="identifier">other</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
  <span class="keyword">void</span> <span class="identifier">assign</span><span class="special">(</span><span class="identifier">Executor</span> <span class="identifier">e</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> <code class="computeroutput"><span class="identifier">executor</span><span class="special">(</span><span class="identifier">allocator_arg</span><span class="special">,</span> <span class="identifier">a</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">e</span><span class="special">)).</span><span class="identifier">swap</span><span class="special">(*</span><span class="keyword">this</span><span class="special">)</span></code>.
          </p></blockquote></div></div><div class="section" title="12.22.5.&#160;executor operations"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__executor__operations"></a>12.22.5.&#160;<code class="literal">executor</code> operations</h4></div></div></div><pre class="programlisting"><span class="identifier">execution_context</span><span class="special">&amp;</span> <span class="identifier">context</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Requires:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span> <span class="special">!=</span> <span class="keyword">nullptr</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">e</span><span class="special">.</span><span class="identifier">context</span><span class="special">()</span></code>, where <code class="computeroutput"><span class="identifier">e</span></code>
            is the target object of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">on_work_started</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Requires:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span> <span class="special">!=</span> <span class="keyword">nullptr</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> <code class="computeroutput"><span class="identifier">e</span><span class="special">.</span><span class="identifier">on_work_started</span><span class="special">()</span></code>, where <code class="computeroutput"><span class="identifier">e</span></code>
            is the target object of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">on_work_finished</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Requires:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span> <span class="special">!=</span> <span class="keyword">nullptr</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> <code class="computeroutput"><span class="identifier">e</span><span class="special">.</span><span class="identifier">on_work_finished</span><span class="special">()</span></code>, where <code class="computeroutput"><span class="identifier">e</span></code>
            is the target object of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
  <span class="keyword">void</span> <span class="identifier">dispatch</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            Let <code class="computeroutput"><span class="identifier">e</span></code> be the target object
            of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
            Let <code class="computeroutput"><span class="identifier">a1</span></code> be the allocator
            that was specified when the target was set. Let <code class="computeroutput"><span class="identifier">fd</span></code>
            be the result of <code class="computeroutput"><span class="identifier">DECAY_COPY</span><span class="special">(</span><span class="identifier">f</span><span class="special">)</span></code> (C++Std [thread.decaycopy]).
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> <code class="computeroutput"><span class="identifier">e</span><span class="special">.</span><span class="identifier">dispatch</span><span class="special">(</span><span class="identifier">g</span><span class="special">,</span> <span class="identifier">a1</span><span class="special">)</span></code>, where <code class="computeroutput"><span class="identifier">g</span></code>
            is a function object of unspecified type that, when called as <code class="computeroutput"><span class="identifier">g</span><span class="special">()</span></code>,
            performs <code class="computeroutput"><span class="identifier">fd</span><span class="special">()</span></code>.
            The allocator <code class="computeroutput"><span class="identifier">a</span></code> is used
            to allocate any memory required to implement <code class="computeroutput"><span class="identifier">g</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
  <span class="keyword">void</span> <span class="identifier">post</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            Let <code class="computeroutput"><span class="identifier">e</span></code> be the target object
            of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
            Let <code class="computeroutput"><span class="identifier">a1</span></code> be the allocator
            that was specified when the target was set. Let <code class="computeroutput"><span class="identifier">fd</span></code>
            be the result of <code class="computeroutput"><span class="identifier">DECAY_COPY</span><span class="special">(</span><span class="identifier">f</span><span class="special">)</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> <code class="computeroutput"><span class="identifier">e</span><span class="special">.</span><span class="identifier">post</span><span class="special">(</span><span class="identifier">g</span><span class="special">,</span> <span class="identifier">a1</span><span class="special">)</span></code>, where <code class="computeroutput"><span class="identifier">g</span></code>
            is a function object of unspecified type that, when called as <code class="computeroutput"><span class="identifier">g</span><span class="special">()</span></code>,
            performs <code class="computeroutput"><span class="identifier">fd</span><span class="special">()</span></code>.
            The allocator <code class="computeroutput"><span class="identifier">a</span></code> is used
            to allocate any memory required to implement <code class="computeroutput"><span class="identifier">g</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
  <span class="keyword">void</span> <span class="identifier">defer</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            Let <code class="computeroutput"><span class="identifier">e</span></code> be the target object
            of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
            Let <code class="computeroutput"><span class="identifier">a1</span></code> be the allocator
            that was specified when the target was set. Let <code class="computeroutput"><span class="identifier">fd</span></code>
            be the result of <code class="computeroutput"><span class="identifier">DECAY_COPY</span><span class="special">(</span><span class="identifier">f</span><span class="special">)</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> <code class="computeroutput"><span class="identifier">e</span><span class="special">.</span><span class="identifier">defer</span><span class="special">(</span><span class="identifier">g</span><span class="special">,</span> <span class="identifier">a1</span><span class="special">)</span></code>, where <code class="computeroutput"><span class="identifier">g</span></code>
            is a function object of unspecified type that, when called as <code class="computeroutput"><span class="identifier">g</span><span class="special">()</span></code>,
            performs <code class="computeroutput"><span class="identifier">fd</span><span class="special">()</span></code>.
            The allocator <code class="computeroutput"><span class="identifier">a</span></code> is used
            to allocate any memory required to implement <code class="computeroutput"><span class="identifier">g</span></code>.
          </p></blockquote></div></div><div class="section" title="12.22.6.&#160;executor capacity"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__executor__capacity"></a>12.22.6.&#160;<code class="literal">executor</code> capacity</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> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="keyword">true</span></code>
            if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
            has a target, otherwise <code class="computeroutput"><span class="keyword">false</span></code>.
          </p></blockquote></div></div><div class="section" title="12.22.7.&#160;executor target access"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__executor__target_access"></a>12.22.7.&#160;<code class="literal">executor</code> target access</h4></div></div></div><pre class="programlisting"><span class="keyword">const</span> <span class="identifier">type_info</span><span class="special">&amp;</span> <span class="identifier">target_type</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> If <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> has a target of type <code class="computeroutput"><span class="identifier">T</span></code>, <code class="computeroutput"><span class="keyword">typeid</span><span class="special">(</span><span class="identifier">T</span><span class="special">)</span></code>; otherwise, <code class="computeroutput"><span class="keyword">typeid</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span> <span class="identifier">Executor</span><span class="special">*</span> <span class="identifier">target</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">*</span> <span class="identifier">target</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> If <code class="computeroutput"><span class="identifier">target_type</span><span class="special">()</span> <span class="special">==</span> <span class="keyword">typeid</span><span class="special">(</span><span class="identifier">Executor</span><span class="special">)</span></code>
            a pointer to the stored executor target; otherwise a null pointer value.
          </p></blockquote></div></div><div class="section" title="12.22.8.&#160;executor comparisons"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__executor__comparisons"></a>12.22.8.&#160;<code class="literal">executor</code> comparisons</h4></div></div></div><pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <br> &#8212; <code class="computeroutput"><span class="keyword">true</span></code>
            if <code class="computeroutput"><span class="special">!</span><span class="identifier">a</span></code>
            and <code class="computeroutput"><span class="special">!</span><span class="identifier">b</span></code>;<br>
            &#8212; <code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="identifier">a</span></code>
            and <code class="computeroutput"><span class="identifier">b</span></code> share a target;<br>
            &#8212; <code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="identifier">e</span></code>
            and <code class="computeroutput"><span class="identifier">f</span></code> are the same type
            and <code class="computeroutput"><span class="identifier">e</span> <span class="special">==</span>
            <span class="identifier">f</span></code>, where <code class="computeroutput"><span class="identifier">e</span></code>
            is the target of <code class="computeroutput"><span class="identifier">a</span></code> and
            <code class="computeroutput"><span class="identifier">f</span></code> is the target of <code class="computeroutput"><span class="identifier">b</span></code>;<br> &#8212; otherwise <code class="computeroutput"><span class="keyword">false</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">,</span> <span class="identifier">nullptr_t</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="identifier">nullptr_t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="special">!</span><span class="identifier">e</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="special">!(</span><span class="identifier">a</span> <span class="special">==</span> <span class="identifier">b</span><span class="special">)</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">,</span> <span class="identifier">nullptr_t</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="identifier">nullptr_t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="special">(</span><span class="keyword">bool</span><span class="special">)</span> <span class="identifier">e</span></code>.
          </p></blockquote></div></div><div class="section" title="12.22.9.&#160;executor specialized algorithms"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__executor__specialized_algorithms"></a>12.22.9.&#160;<code class="literal">executor</code> specialized algorithms</h4></div></div></div><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">executor</span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> <code class="computeroutput"><span class="identifier">a</span><span class="special">.</span><span class="identifier">swap</span><span class="special">(</span><span class="identifier">b</span><span class="special">)</span></code>.
          </p></blockquote></div></div></div><div class="section" title="12.23.&#160;Function dispatch"><div class="titlepage"><div><div><h3 class="title"><a name="functions.dispatch"></a>12.23.&#160;Function <code class="literal">dispatch</code></h3></div></div></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
  <span class="emphasis"><em>DEDUCED</em></span> <span class="identifier">dispatch</span><span class="special">(</span><span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Effects:</em></span> <br> &#8212; Constructs an object <code class="computeroutput"><span class="identifier">completion</span></code> of type <code class="computeroutput"><span class="identifier">async_completion</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">,</span> <span class="keyword">void</span><span class="special">()&gt;</span></code>,
          initialized with <code class="computeroutput"><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;(</span><span class="identifier">token</span><span class="special">)</span></code>.<br> &#8212; Performs <code class="computeroutput"><span class="identifier">ex</span><span class="special">.</span><span class="identifier">dispatch</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">completion</span><span class="special">.</span><span class="identifier">completion_handler</span><span class="special">),</span> <span class="identifier">alloc</span><span class="special">)</span></code>, where <code class="computeroutput"><span class="identifier">ex</span></code>
          is the result of <code class="computeroutput"><span class="identifier">get_associated_executor</span><span class="special">(</span><span class="identifier">completion</span><span class="special">.</span><span class="identifier">completion_handler</span><span class="special">)</span></code>, and <code class="computeroutput"><span class="identifier">alloc</span></code>
          is the result of <code class="computeroutput"><span class="identifier">get_associated_allocator</span><span class="special">(</span><span class="identifier">completion</span><span class="special">.</span><span class="identifier">completion_handler</span><span class="special">)</span></code>.
        </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">completion</span><span class="special">.</span><span class="identifier">result</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span></code>.
        </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
  <span class="emphasis"><em>DEDUCED</em></span> <span class="identifier">dispatch</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">&amp;</span> <span class="identifier">ex</span><span class="special">,</span> <span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Effects:</em></span> <br> &#8212; Constructs an object <code class="computeroutput"><span class="identifier">completion</span></code> of type <code class="computeroutput"><span class="identifier">async_completion</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">,</span> <span class="keyword">void</span><span class="special">()&gt;</span></code>,
          initialized with <code class="computeroutput"><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;(</span><span class="identifier">token</span><span class="special">)</span></code>.<br> &#8212; Constructs a function object <code class="computeroutput"><span class="identifier">f</span></code> containing as members:<br> &#160;&#160;&#160;&#160;&#8226; a copy
          of the completion handler <code class="computeroutput"><span class="identifier">h</span></code>,
          initialized with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">completion</span><span class="special">.</span><span class="identifier">completion_handler</span><span class="special">)</span></code>,<br>
          &#160;&#160;&#160;&#160;&#8226; an <code class="computeroutput"><span class="identifier">executor_work_guard</span></code>
          object <code class="computeroutput"><span class="identifier">w</span></code> for the completion
          handler's associated executor, initialized with <code class="computeroutput"><span class="identifier">make_work_guard</span><span class="special">(</span><span class="identifier">h</span><span class="special">)</span></code>,<br>
          &#160;&#160;&#160;&#160;and where the effect of <code class="computeroutput"><span class="identifier">f</span><span class="special">()</span></code> is:<br> &#160;&#160;&#160;&#160;&#8226; <code class="computeroutput"><span class="identifier">w</span><span class="special">.</span><span class="identifier">get_executor</span><span class="special">().</span><span class="identifier">dispatch</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">h</span><span class="special">),</span>
          <span class="identifier">alloc</span><span class="special">)</span></code>,
          where <code class="computeroutput"><span class="identifier">alloc</span></code> is the result
          of <code class="computeroutput"><span class="identifier">get_associated_allocator</span><span class="special">(</span><span class="identifier">h</span><span class="special">)</span></code>,
          followed by<br> &#160;&#160;&#160;&#160;&#8226; <code class="computeroutput"><span class="identifier">w</span><span class="special">.</span><span class="identifier">reset</span><span class="special">()</span></code>.<br>
          &#8212; Performs <code class="computeroutput"><span class="identifier">ex</span><span class="special">.</span><span class="identifier">dispatch</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">alloc</span><span class="special">)</span></code>,
          where <code class="computeroutput"><span class="identifier">alloc</span></code> is the result
          of <code class="computeroutput"><span class="identifier">get_associated_allocator</span><span class="special">(</span><span class="identifier">completion</span><span class="special">.</span><span class="identifier">completion_handler</span><span class="special">)</span></code> prior to the construction of <code class="computeroutput"><span class="identifier">f</span></code>.
        </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">completion</span><span class="special">.</span><span class="identifier">result</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span></code>.
        </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Remarks:</em></span> This function shall not participate in overload
          resolution unless <code class="computeroutput"><span class="identifier">is_executor</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;::</span><span class="identifier">value</span></code>
          is <code class="computeroutput"><span class="keyword">true</span></code>.
        </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ExecutionContext</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
  <span class="emphasis"><em>DEDUCED</em></span> <span class="identifier">dispatch</span><span class="special">(</span><span class="identifier">ExecutionContext</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">,</span> <span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">experimental</span><span class="special">::</span>concurrency<span class="special">::</span><span class="identifier">dispatch</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">.</span><span class="identifier">get_executor</span><span class="special">(),</span>
          <span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;(</span><span class="identifier">token</span><span class="special">))</span></code>.
        </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Remarks:</em></span> This function shall not participate in overload
          resolution unless <code class="computeroutput"><span class="identifier">is_convertible</span><span class="special">&lt;</span><span class="identifier">ExecutionContext</span><span class="special">&amp;,</span> <span class="identifier">execution_context</span><span class="special">&amp;&gt;::</span><span class="identifier">value</span></code>
          is <code class="computeroutput"><span class="keyword">true</span></code>.
        </p></blockquote></div></div><div class="section" title="12.24.&#160;Function post"><div class="titlepage"><div><div><h3 class="title"><a name="functions.post"></a>12.24.&#160;Function <code class="literal">post</code></h3></div></div></div><p>
        [<span class="emphasis"><em>Note:</em></span> The function <code class="computeroutput"><span class="identifier">post</span></code>
        satisfies the requirements for an <a class="link" href="#requirements.asynchronous_operations" title="12.3.7.&#160;Requirements on asynchronous operations">asynchronous
        operation</a>. &#8212;<span class="emphasis"><em>end note</em></span>]
      </p><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
  <span class="emphasis"><em>DEDUCED</em></span> <span class="identifier">post</span><span class="special">(</span><span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Effects:</em></span> <br> &#8212; Constructs an object <code class="computeroutput"><span class="identifier">completion</span></code> of type <code class="computeroutput"><span class="identifier">async_completion</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">,</span> <span class="keyword">void</span><span class="special">()&gt;</span></code>,
          initialized with <code class="computeroutput"><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;(</span><span class="identifier">token</span><span class="special">)</span></code>.<br> &#8212; Performs <code class="computeroutput"><span class="identifier">ex</span><span class="special">.</span><span class="identifier">post</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">completion</span><span class="special">.</span><span class="identifier">completion_handler</span><span class="special">),</span> <span class="identifier">alloc</span><span class="special">)</span></code>, where <code class="computeroutput"><span class="identifier">ex</span></code>
          is the result of <code class="computeroutput"><span class="identifier">get_associated_executor</span><span class="special">(</span><span class="identifier">completion</span><span class="special">.</span><span class="identifier">completion_handler</span><span class="special">)</span></code>, and <code class="computeroutput"><span class="identifier">alloc</span></code>
          is the result of <code class="computeroutput"><span class="identifier">get_associated_allocator</span><span class="special">(</span><span class="identifier">completion</span><span class="special">.</span><span class="identifier">completion_handler</span><span class="special">)</span></code>.
        </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">completion</span><span class="special">.</span><span class="identifier">result</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span></code>.
        </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
  <span class="emphasis"><em>DEDUCED</em></span> <span class="identifier">post</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">&amp;</span> <span class="identifier">ex</span><span class="special">,</span> <span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Effects:</em></span> <br> &#8212; Constructs an object <code class="computeroutput"><span class="identifier">completion</span></code> of type <code class="computeroutput"><span class="identifier">async_completion</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">,</span> <span class="keyword">void</span><span class="special">()&gt;</span></code>,
          initialized with <code class="computeroutput"><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;(</span><span class="identifier">token</span><span class="special">)</span></code>.<br> &#8212; Constructs a function object <code class="computeroutput"><span class="identifier">f</span></code> containing as members:<br> &#160;&#160;&#160;&#160;&#8226; a copy
          of the completion handler <code class="computeroutput"><span class="identifier">h</span></code>,
          initialized with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">completion</span><span class="special">.</span><span class="identifier">completion_handler</span><span class="special">)</span></code>,<br>
          &#160;&#160;&#160;&#160;&#8226; an <code class="computeroutput"><span class="identifier">executor_work_guard</span></code>
          object <code class="computeroutput"><span class="identifier">w</span></code> for the completion
          handler's associated executor, initialized with <code class="computeroutput"><span class="identifier">make_work_guard</span><span class="special">(</span><span class="identifier">h</span><span class="special">)</span></code>,<br>
          &#160;&#160;&#160;&#160;and where the effect of <code class="computeroutput"><span class="identifier">f</span><span class="special">()</span></code> is:<br> &#160;&#160;&#160;&#160;&#8226; <code class="computeroutput"><span class="identifier">w</span><span class="special">.</span><span class="identifier">get_executor</span><span class="special">().</span><span class="identifier">dispatch</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">h</span><span class="special">),</span>
          <span class="identifier">alloc</span><span class="special">)</span></code>,
          where <code class="computeroutput"><span class="identifier">alloc</span></code> is the result
          of <code class="computeroutput"><span class="identifier">get_associated_allocator</span><span class="special">(</span><span class="identifier">h</span><span class="special">)</span></code>,
          followed by<br> &#160;&#160;&#160;&#160;&#8226; <code class="computeroutput"><span class="identifier">w</span><span class="special">.</span><span class="identifier">reset</span><span class="special">()</span></code>.<br>
          &#8212; Performs <code class="computeroutput"><span class="identifier">ex</span><span class="special">.</span><span class="identifier">post</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">alloc</span><span class="special">)</span></code>,
          where <code class="computeroutput"><span class="identifier">alloc</span></code> is the result
          of <code class="computeroutput"><span class="identifier">get_associated_allocator</span><span class="special">(</span><span class="identifier">completion</span><span class="special">.</span><span class="identifier">completion_handler</span><span class="special">)</span></code> prior to the construction of <code class="computeroutput"><span class="identifier">f</span></code>.
        </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">completion</span><span class="special">.</span><span class="identifier">result</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span></code>.
        </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Remarks:</em></span> This function shall not participate in overload
          resolution unless <code class="computeroutput"><span class="identifier">is_executor</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;::</span><span class="identifier">value</span></code>
          is <code class="computeroutput"><span class="keyword">true</span></code>.
        </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ExecutionContext</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
  <span class="emphasis"><em>DEDUCED</em></span> <span class="identifier">post</span><span class="special">(</span><span class="identifier">ExecutionContext</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">,</span> <span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">experimental</span><span class="special">::</span>concurrency<span class="special">::</span><span class="identifier">post</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">.</span><span class="identifier">get_executor</span><span class="special">(),</span>
          <span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;(</span><span class="identifier">token</span><span class="special">))</span></code>.
        </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Remarks:</em></span> This function shall not participate in overload
          resolution unless <code class="computeroutput"><span class="identifier">is_convertible</span><span class="special">&lt;</span><span class="identifier">ExecutionContext</span><span class="special">&amp;,</span> <span class="identifier">execution_context</span><span class="special">&amp;&gt;::</span><span class="identifier">value</span></code>
          is <code class="computeroutput"><span class="keyword">true</span></code>.
        </p></blockquote></div></div><div class="section" title="12.25.&#160;Function defer"><div class="titlepage"><div><div><h3 class="title"><a name="functions.defer"></a>12.25.&#160;Function <code class="literal">defer</code></h3></div></div></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
  <span class="emphasis"><em>DEDUCED</em></span> <span class="identifier">defer</span><span class="special">(</span><span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Effects:</em></span> <br> &#8212; Constructs an object <code class="computeroutput"><span class="identifier">completion</span></code> of type <code class="computeroutput"><span class="identifier">async_completion</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">,</span> <span class="keyword">void</span><span class="special">()&gt;</span></code>,
          initialized with <code class="computeroutput"><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;(</span><span class="identifier">token</span><span class="special">)</span></code>.<br> &#8212; Performs <code class="computeroutput"><span class="identifier">ex</span><span class="special">.</span><span class="identifier">defer</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">completion</span><span class="special">.</span><span class="identifier">completion_handler</span><span class="special">),</span> <span class="identifier">alloc</span><span class="special">)</span></code>, where <code class="computeroutput"><span class="identifier">ex</span></code>
          is the result of <code class="computeroutput"><span class="identifier">get_associated_executor</span><span class="special">(</span><span class="identifier">completion</span><span class="special">.</span><span class="identifier">completion_handler</span><span class="special">)</span></code>, and <code class="computeroutput"><span class="identifier">alloc</span></code>
          is the result of <code class="computeroutput"><span class="identifier">get_associated_allocator</span><span class="special">(</span><span class="identifier">completion</span><span class="special">.</span><span class="identifier">completion_handler</span><span class="special">)</span></code>.
        </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">completion</span><span class="special">.</span><span class="identifier">result</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span></code>.
        </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
  <span class="emphasis"><em>DEDUCED</em></span> <span class="identifier">defer</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Executor</span><span class="special">&amp;</span> <span class="identifier">ex</span><span class="special">,</span> <span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Effects:</em></span> <br> &#8212; Constructs an object <code class="computeroutput"><span class="identifier">completion</span></code> of type <code class="computeroutput"><span class="identifier">async_completion</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">,</span> <span class="keyword">void</span><span class="special">()&gt;</span></code>,
          initialized with <code class="computeroutput"><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;(</span><span class="identifier">token</span><span class="special">)</span></code>.<br> &#8212; Constructs a function object <code class="computeroutput"><span class="identifier">f</span></code> containing as members:<br> &#160;&#160;&#160;&#160;&#8226; a copy
          of the completion handler <code class="computeroutput"><span class="identifier">h</span></code>,
          initialized with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">completion</span><span class="special">.</span><span class="identifier">completion_handler</span><span class="special">)</span></code>,<br>
          &#160;&#160;&#160;&#160;&#8226; an <code class="computeroutput"><span class="identifier">executor_work_guard</span></code>
          object <code class="computeroutput"><span class="identifier">w</span></code> for the completion
          handler's associated executor, initialized with <code class="computeroutput"><span class="identifier">make_work_guard</span><span class="special">(</span><span class="identifier">h</span><span class="special">)</span></code>,<br>
          &#160;&#160;&#160;&#160;and where the effect of <code class="computeroutput"><span class="identifier">f</span><span class="special">()</span></code> is:<br> &#160;&#160;&#160;&#160;&#8226; <code class="computeroutput"><span class="identifier">w</span><span class="special">.</span><span class="identifier">get_executor</span><span class="special">().</span><span class="identifier">dispatch</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">h</span><span class="special">),</span>
          <span class="identifier">alloc</span><span class="special">)</span></code>,
          where <code class="computeroutput"><span class="identifier">alloc</span></code> is the result
          of <code class="computeroutput"><span class="identifier">get_associated_allocator</span><span class="special">(</span><span class="identifier">h</span><span class="special">)</span></code>,
          followed by<br> &#160;&#160;&#160;&#160;&#8226; <code class="computeroutput"><span class="identifier">w</span><span class="special">.</span><span class="identifier">reset</span><span class="special">()</span></code>.<br>
          &#8212; Performs <code class="computeroutput"><span class="identifier">ex</span><span class="special">.</span><span class="identifier">defer</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">alloc</span><span class="special">)</span></code>,
          where <code class="computeroutput"><span class="identifier">alloc</span></code> is the result
          of <code class="computeroutput"><span class="identifier">get_associated_allocator</span><span class="special">(</span><span class="identifier">completion</span><span class="special">.</span><span class="identifier">completion_handler</span><span class="special">)</span></code> prior to the construction of <code class="computeroutput"><span class="identifier">f</span></code>.
        </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">completion</span><span class="special">.</span><span class="identifier">result</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span></code>.
        </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Remarks:</em></span> This function shall not participate in overload
          resolution unless <code class="computeroutput"><span class="identifier">is_executor</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;::</span><span class="identifier">value</span></code>
          is <code class="computeroutput"><span class="keyword">true</span></code>.
        </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ExecutionContext</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
  <span class="emphasis"><em>DEDUCED</em></span> <span class="identifier">defer</span><span class="special">(</span><span class="identifier">ExecutionContext</span><span class="special">&amp;</span> <span class="identifier">ctx</span><span class="special">,</span> <span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">experimental</span><span class="special">::</span>concurrency<span class="special">::</span><span class="identifier">defer</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">.</span><span class="identifier">get_executor</span><span class="special">(),</span>
          <span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;(</span><span class="identifier">token</span><span class="special">))</span></code>.
        </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Remarks:</em></span> This function shall not participate in overload
          resolution unless <code class="computeroutput"><span class="identifier">is_convertible</span><span class="special">&lt;</span><span class="identifier">ExecutionContext</span><span class="special">&amp;,</span> <span class="identifier">execution_context</span><span class="special">&amp;&gt;::</span><span class="identifier">value</span></code>
          is <code class="computeroutput"><span class="keyword">true</span></code>.
        </p></blockquote></div></div><div class="section" title="12.26.&#160;Class template strand"><div class="titlepage"><div><div><h3 class="title"><a name="classes.strand"></a>12.26.&#160;Class template <code class="literal">strand</code></h3></div></div></div><p>
        The class template <code class="computeroutput"><span class="identifier">strand</span></code>
        is a wrapper around an object of type <code class="computeroutput"><span class="identifier">Executor</span></code>
        satisfying the <a class="link" href="#requirements.executor" title="12.3.3.&#160;Executor requirements">Executor requirements</a>.
      </p><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
  <span class="keyword">class</span> <span class="identifier">strand</span>
  <span class="special">{</span>
  <span class="keyword">public</span><span class="special">:</span>
    <span class="comment">// types:</span>

    <span class="keyword">typedef</span> <span class="identifier">Executor</span> <span class="identifier">inner_executor_type</span><span class="special">;</span>

    <span class="comment">// construct / copy / destroy:</span>

    <span class="identifier">strand</span><span class="special">();</span>
    <span class="keyword">explicit</span> <span class="identifier">strand</span><span class="special">(</span><span class="identifier">Executor</span> <span class="identifier">ex</span><span class="special">);</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
      <span class="identifier">strand</span><span class="special">(</span><span class="identifier">allocator_arg_t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">alloc</span><span class="special">,</span> <span class="identifier">Executor</span> <span class="identifier">ex</span><span class="special">);</span>
    <span class="identifier">strand</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">strand</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="identifier">strand</span><span class="special">(</span><span class="identifier">strand</span><span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;</span> <span class="identifier">strand</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">OtherExecutor</span><span class="special">&gt;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;</span> <span class="identifier">strand</span><span class="special">(</span><span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">OtherExecutor</span><span class="special">&gt;&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="identifier">strand</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">strand</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="identifier">strand</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">strand</span><span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;</span> <span class="identifier">strand</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">OtherExecutor</span><span class="special">&gt;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;</span> <span class="identifier">strand</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">OtherExecutor</span><span class="special">&gt;&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>

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

    <span class="comment">// strand operations:</span>

    <span class="identifier">inner_executor_type</span> <span class="identifier">get_inner_executor</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="keyword">bool</span> <span class="identifier">running_in_this_thread</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="identifier">execution_context</span><span class="special">&amp;</span> <span class="identifier">context</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="keyword">void</span> <span class="identifier">on_work_started</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">void</span> <span class="identifier">on_work_finished</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
      <span class="keyword">void</span> <span class="identifier">dispatch</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
      <span class="keyword">void</span> <span class="identifier">post</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
      <span class="keyword">void</span> <span class="identifier">defer</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>

  <span class="keyword">private</span><span class="special">:</span>
    <span class="identifier">Executor</span> <span class="identifier">inner_ex_</span><span class="special">;</span> <span class="comment">// <span class="emphasis"><em>exposition only</em></span></span>
  <span class="special">};</span>

  <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;&amp;</span> <span class="identifier">b</span><span class="special">);</span>
  <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="keyword">const</span> <span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;&amp;</span> <span class="identifier">b</span><span class="special">);</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>
</pre><p>
        <code class="computeroutput"><span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;</span></code>
        satisfies the <a class="link" href="#requirements.executor" title="12.3.3.&#160;Executor requirements"><code class="computeroutput"><span class="identifier">Executor</span></code></a>
        requirements.
      </p><p>
        A strand provides guarantees of ordering and non-concurrency. Given:
      </p><p>
        &#8212; strand objects <code class="computeroutput"><span class="identifier">s1</span></code> and <code class="computeroutput"><span class="identifier">s2</span></code> such that <code class="computeroutput"><span class="identifier">s1</span>
        <span class="special">==</span> <span class="identifier">s2</span></code>
      </p><p>
        &#8212; a function object <code class="computeroutput"><span class="identifier">f1</span></code> added
        to the strand <code class="computeroutput"><span class="identifier">s1</span></code> using <code class="computeroutput"><span class="identifier">post</span></code> or <code class="computeroutput"><span class="identifier">defer</span></code>,
        or using <code class="computeroutput"><span class="identifier">dispatch</span></code> when <code class="computeroutput"><span class="identifier">s1</span><span class="special">.</span><span class="identifier">running_in_this_thread</span><span class="special">()</span> <span class="special">==</span> <span class="keyword">false</span></code>
      </p><p>
        &#8212; a function object <code class="computeroutput"><span class="identifier">f2</span></code> added
        to the strand <code class="computeroutput"><span class="identifier">s2</span></code> using <code class="computeroutput"><span class="identifier">post</span></code> or <code class="computeroutput"><span class="identifier">defer</span></code>,
        or using <code class="computeroutput"><span class="identifier">dispatch</span></code> when <code class="computeroutput"><span class="identifier">s2</span><span class="special">.</span><span class="identifier">running_in_this_thread</span><span class="special">()</span> <span class="special">==</span> <span class="keyword">false</span></code>
      </p><p>
        then the implementation invokes <code class="computeroutput"><span class="identifier">f1</span></code>
        and <code class="computeroutput"><span class="identifier">f2</span></code> such that:
      </p><p>
        &#8212; the invocation of <code class="computeroutput"><span class="identifier">f1</span></code> is not
        concurrent with the invocation of <code class="computeroutput"><span class="identifier">f2</span></code>
      </p><p>
        &#8212; the invocation of <code class="computeroutput"><span class="identifier">f1</span></code> synchronizes
        with the invocation of <code class="computeroutput"><span class="identifier">f2</span></code>.
      </p><p>
        Furthermore, if the addition of <code class="computeroutput"><span class="identifier">f1</span></code>
        happens before the addition of <code class="computeroutput"><span class="identifier">f2</span></code>,
        then the invocation of <code class="computeroutput"><span class="identifier">f1</span></code>
        happens before the invocation of <code class="computeroutput"><span class="identifier">f2</span></code>.
      </p><p>
        All member functions, except for the assignment operators and the destructor,
        do not introduce data races on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>, including its ordered, non-concurrent
        state. Additionally, constructors and assignment operators do not introduce
        data races on lvalue arguments.
      </p><p>
        If any function <code class="computeroutput"><span class="identifier">f</span></code> executed
        by the strand throws an exception, the subsequent strand state is as if
        <code class="computeroutput"><span class="identifier">f</span></code> had exited without throwing
        an exception.
      </p><div class="section" title="12.26.1.&#160;strand constructors"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__strand__constructors"></a>12.26.1.&#160;<code class="literal">strand</code> constructors</h4></div></div></div><pre class="programlisting"><span class="identifier">strand</span><span class="special">();</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Constructs an object of class <code class="computeroutput"><span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;</span></code>
            that represents a unique ordered, non-concurrent state. Initializes
            <code class="computeroutput"><span class="identifier">inner_ex_</span></code> with <code class="computeroutput"><span class="identifier">inner_ex_</span><span class="special">()</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Remarks:</em></span> This overload shall not participate in
            overload resolution unless <code class="computeroutput"><span class="identifier">Executor</span></code>
            satisfies the <code class="computeroutput"><span class="identifier">DefaultConstructible</span></code>
            requirements (C++Std [defaultconstructible]).
          </p></blockquote></div><pre class="programlisting"><span class="keyword">explicit</span> <span class="identifier">strand</span><span class="special">(</span><span class="identifier">Executor</span> <span class="identifier">ex</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Constructs an object of class <code class="computeroutput"><span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;</span></code>
            that represents a unique ordered, non-concurrent state. Initializes
            <code class="computeroutput"><span class="identifier">inner_ex_</span></code> as <code class="computeroutput"><span class="identifier">inner_ex_</span><span class="special">(</span><span class="identifier">ex</span><span class="special">)</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
  <span class="identifier">strand</span><span class="special">(</span><span class="identifier">allocator_arg_t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">Executor</span> <span class="identifier">ex</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Constructs an object of class <code class="computeroutput"><span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;</span></code>
            that represents a unique ordered, non-concurrent state. Initializes
            <code class="computeroutput"><span class="identifier">inner_ex_</span></code> as <code class="computeroutput"><span class="identifier">inner_ex_</span><span class="special">(</span><span class="identifier">ex</span><span class="special">)</span></code>.
            A copy of the allocator argument <code class="computeroutput"><span class="identifier">a</span></code>
            is used to allocate memory, if necessary, for the internal data structures
            of the constructed strand object.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">strand</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">strand</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Initializes <code class="computeroutput"><span class="identifier">inner_ex_</span></code>
            as <code class="computeroutput"><span class="identifier">inner_ex_</span><span class="special">(</span><span class="identifier">other</span><span class="special">.</span><span class="identifier">inner_ex_</span><span class="special">)</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <br> &#8212; <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span> <span class="special">==</span> <span class="identifier">other</span></code><br> &#8212; <code class="computeroutput"><span class="identifier">get_inner_executor</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">other</span><span class="special">.</span><span class="identifier">get_inner_executor</span><span class="special">()</span></code>
          </p></blockquote></div><pre class="programlisting"><span class="identifier">strand</span><span class="special">(</span><span class="identifier">strand</span><span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Initializes <code class="computeroutput"><span class="identifier">inner_ex_</span></code>
            with <code class="computeroutput"><span class="identifier">inner_ex_</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">inner_ex_</span><span class="special">))</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <br> &#8212; <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is equal to the prior value of <code class="computeroutput"><span class="identifier">other</span></code><br> &#8212; <code class="computeroutput"><span class="identifier">get_inner_executor</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">other</span><span class="special">.</span><span class="identifier">get_inner_executor</span><span class="special">()</span></code>
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;</span> <span class="identifier">strand</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">OtherExecutor</span><span class="special">&gt;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Requires:</em></span> <code class="computeroutput"><span class="identifier">OtherExecutor</span></code>
            is convertible to <code class="computeroutput"><span class="identifier">Executor</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Initializes <code class="computeroutput"><span class="identifier">inner_ex_</span></code>
            with <code class="computeroutput"><span class="identifier">inner_ex_</span><span class="special">(</span><span class="identifier">other</span><span class="special">.</span><span class="identifier">inner_ex_</span><span class="special">)</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span> <span class="special">==</span> <span class="identifier">other</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;</span> <span class="identifier">strand</span><span class="special">(</span><span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">OtherExecutor</span><span class="special">&gt;&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Requires:</em></span> <code class="computeroutput"><span class="identifier">OtherExecutor</span></code>
            is convertible to <code class="computeroutput"><span class="identifier">Executor</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Initializes <code class="computeroutput"><span class="identifier">inner_ex_</span></code>
            with <code class="computeroutput"><span class="identifier">inner_ex_</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">inner_ex_</span><span class="special">))</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is equal to the prior value of <code class="computeroutput"><span class="identifier">other</span></code>.
          </p></blockquote></div></div><div class="section" title="12.26.2.&#160;strand assignment"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__strand__assignment"></a>12.26.2.&#160;<code class="literal">strand</code> assignment</h4></div></div></div><pre class="programlisting"><span class="identifier">strand</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">strand</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Requires:</em></span> <code class="computeroutput"><span class="identifier">Executor</span></code>
            is <code class="computeroutput"><span class="identifier">CopyAssignable</span></code> (C++Std
            [copyassignable]).
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <br> &#8212; <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span> <span class="special">==</span> <span class="identifier">other</span></code><br> &#8212; <code class="computeroutput"><span class="identifier">get_inner_executor</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">other</span><span class="special">.</span><span class="identifier">get_inner_executor</span><span class="special">()</span></code>
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">strand</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">strand</span><span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Requires:</em></span> <code class="computeroutput"><span class="identifier">Executor</span></code>
            is <code class="computeroutput"><span class="identifier">MoveAssignable</span></code> (C++Std
            [moveassignable]).
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <br> &#8212; <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is equal to the prior value of <code class="computeroutput"><span class="identifier">other</span></code><br> &#8212; <code class="computeroutput"><span class="identifier">get_inner_executor</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">other</span><span class="special">.</span><span class="identifier">get_inner_executor</span><span class="special">()</span></code>
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;</span> <span class="identifier">strand</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">OtherExecutor</span><span class="special">&gt;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Requires:</em></span> <code class="computeroutput"><span class="identifier">OtherExecutor</span></code>
            is convertible to <code class="computeroutput"><span class="identifier">Executor</span></code>.
            <code class="computeroutput"><span class="identifier">Executor</span></code> is <code class="computeroutput"><span class="identifier">CopyAssignable</span></code> (C++Std [copyassignable]).
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Assigns <code class="computeroutput"><span class="identifier">other</span><span class="special">.</span><span class="identifier">inner_ex_</span></code>
            to <code class="computeroutput"><span class="identifier">inner_ex_</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span> <span class="special">==</span> <span class="identifier">other</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">OtherExecutor</span><span class="special">&gt;</span> <span class="identifier">strand</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">OtherExecutor</span><span class="special">&gt;&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Requires:</em></span> <code class="computeroutput"><span class="identifier">OtherExecutor</span></code>
            is convertible to <code class="computeroutput"><span class="identifier">Executor</span></code>.
            <code class="computeroutput"><span class="identifier">Executor</span></code> is <code class="computeroutput"><span class="identifier">MoveAssignable</span></code> (C++Std [moveassignable]).
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Assigns <code class="computeroutput"><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">inner_ex_</span><span class="special">)</span></code> to <code class="computeroutput"><span class="identifier">inner_ex_</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is equal to the prior value of <code class="computeroutput"><span class="identifier">other</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
          </p></blockquote></div></div><div class="section" title="12.26.3.&#160;strand destructor"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__strand__destructor"></a>12.26.3.&#160;<code class="literal">strand</code> destructor</h4></div></div></div><pre class="programlisting"><span class="special">~</span><span class="identifier">strand</span><span class="special">();</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Destroys an object of class <code class="computeroutput"><span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;</span></code>.
            After this destructor completes, objects that were added to the strand
            but have not yet been executed will be executed in a way that meets the
            guarantees of ordering and non-concurrency.
          </p></blockquote></div></div><div class="section" title="12.26.4.&#160;strand operations"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__strand__operations"></a>12.26.4.&#160;<code class="literal">strand</code> operations</h4></div></div></div><pre class="programlisting"><span class="identifier">inner_executor_type</span> <span class="identifier">get_inner_executor</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">inner_ex_</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">running_in_this_thread</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="keyword">true</span></code>
            if the current thread of execution is running a function that was submitted
            to the strand, or to any other strand object <code class="computeroutput"><span class="identifier">s</span></code>
            such that <code class="computeroutput"><span class="identifier">s</span> <span class="special">==</span>
            <span class="special">*</span><span class="keyword">this</span></code>,
            using <code class="computeroutput"><span class="identifier">dispatch</span></code>, <code class="computeroutput"><span class="identifier">post</span></code> or <code class="computeroutput"><span class="identifier">defer</span></code>;
            otherwise <code class="computeroutput"><span class="keyword">false</span></code>. [<span class="emphasis"><em>Note:</em></span>
            That is, the current thread of execution's call chain includes a function
            that was submitted to the strand. &#8212;<span class="emphasis"><em>end note</em></span>]
          </p></blockquote></div><pre class="programlisting"><span class="identifier">execution_context</span><span class="special">&amp;</span> <span class="identifier">context</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">inner_ex_</span><span class="special">.</span><span class="identifier">context</span><span class="special">()</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">on_work_started</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Calls <code class="computeroutput"><span class="identifier">inner_ex_</span><span class="special">.</span><span class="identifier">on_work_started</span><span class="special">()</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">on_work_finished</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Calls <code class="computeroutput"><span class="identifier">inner_ex_</span><span class="special">.</span><span class="identifier">on_work_finished</span><span class="special">()</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
  <span class="keyword">void</span> <span class="identifier">dispatch</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> If <code class="computeroutput"><span class="identifier">running_in_this_thread</span><span class="special">()</span> <span class="special">==</span> <span class="keyword">true</span></code>, calls <code class="literal"><span class="emphasis"><em>DECAY_COPY</em></span></code><code class="computeroutput"><span class="special">(</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Func</span><span class="special">&gt;(</span><span class="identifier">f</span><span class="special">))()</span></code> (C++Std [thread.decaycopy]). [<span class="emphasis"><em>Note:</em></span>
            If <code class="computeroutput"><span class="identifier">f</span></code> exits via an exception,
            the exception propagates to the caller of <code class="computeroutput"><span class="identifier">dispatch</span><span class="special">()</span></code>. &#8212;<span class="emphasis"><em>end note</em></span>] Otherwise,
            requests invocation of <code class="computeroutput"><span class="identifier">f</span></code>,
            as if by forwarding the function object <code class="computeroutput"><span class="identifier">f</span></code>
            and allocator <code class="computeroutput"><span class="identifier">a</span></code> to the
            executor <code class="computeroutput"><span class="identifier">inner_ex_</span></code>, such
            that the guarantees of ordering and non-concurrency are met.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
  <span class="keyword">void</span> <span class="identifier">post</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Requests invocation of <code class="computeroutput"><span class="identifier">f</span></code>,
            as if by forwarding the function object <code class="computeroutput"><span class="identifier">f</span></code>
            and allocator <code class="computeroutput"><span class="identifier">a</span></code> to the
            executor <code class="computeroutput"><span class="identifier">inner_ex_</span></code>, such
            that the guarantees of ordering and non-concurrency are met.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
  <span class="keyword">void</span> <span class="identifier">defer</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Requests invocation of <code class="computeroutput"><span class="identifier">f</span></code>,
            as if by forwarding the function object <code class="computeroutput"><span class="identifier">f</span></code>
            and allocator <code class="computeroutput"><span class="identifier">a</span></code> to the
            executor <code class="computeroutput"><span class="identifier">inner_ex_</span></code>, such
            that the guarantees of ordering and non-concurrency are met.
          </p></blockquote></div></div><div class="section" title="12.26.5.&#160;strand comparisons"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__strand__comparisons"></a>12.26.5.&#160;<code class="literal">strand</code> comparisons</h4></div></div></div><pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;&amp;</span> <span class="identifier">b</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="keyword">true</span></code>,
            if the strand objects share the same ordered, non-concurrent state; otherwise
            <code class="computeroutput"><span class="keyword">false</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="keyword">const</span> <span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;&amp;</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">strand</span><span class="special">&lt;</span><span class="identifier">Executor</span><span class="special">&gt;&amp;</span> <span class="identifier">b</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="special">!(</span><span class="identifier">a</span> <span class="special">==</span> <span class="identifier">b</span><span class="special">)</span></code>.
          </p></blockquote></div></div></div><div class="section" title="12.27.&#160;Class template use_future_t"><div class="titlepage"><div><div><h3 class="title"><a name="classes.use_future_t"></a>12.27.&#160;Class template <code class="literal">use_future_t</code></h3></div></div></div><p>
        The class template <code class="computeroutput"><span class="identifier">use_future_t</span></code>
        defines a set of types that, when passed as a <a class="link" href="#requirements.completion_token" title="12.3.7.2.&#160;Completion tokens and handlers">completion
        token</a> to an asynchronous operation's initiating function, cause the
        result of the asynchronous operation to be delivered via a future (C++Std
        [futures.unique_future]).
      </p><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ProtoAllocator</span> <span class="special">=</span> <span class="identifier">allocator</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;&gt;</span>
  <span class="keyword">class</span> <span class="identifier">use_future_t</span>
  <span class="special">{</span>
  <span class="keyword">public</span><span class="special">:</span>
    <span class="comment">// use_future_t types:</span>
    <span class="keyword">typedef</span> <span class="identifier">ProtoAllocator</span> <span class="identifier">allocator_type</span><span class="special">;</span>

    <span class="comment">// use_future_t members:</span>
    <span class="keyword">constexpr</span> <span class="identifier">use_future_t</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">explicit</span> <span class="identifier">use_future_t</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">allocator_type</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">OtherProtoAllocator</span><span class="special">&gt;</span> <span class="identifier">use_future_t</span><span class="special">&lt;</span><span class="identifier">OtherProtoAllocator</span><span class="special">&gt;</span>
      <span class="identifier">rebind</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">OtherProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="identifier">allocator_type</span> <span class="identifier">get_allocator</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</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="emphasis"><em>unspecified</em></span> <span class="keyword">operator</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">const</span><span class="special">;</span>
  <span class="special">};</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>
</pre><div class="section" title="12.27.1.&#160;use_future_t constructors"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__use_future_t__constructors"></a>12.27.1.&#160;<code class="literal">use_future_t</code> constructors</h4></div></div></div><pre class="programlisting"><span class="keyword">constexpr</span> <span class="identifier">use_future_t</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Constructs a <code class="computeroutput"><span class="identifier">use_future_t</span></code>
            with a default-constructed allocator.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">explicit</span> <span class="identifier">use_future_t</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">allocator_type</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="identifier">get_allocator</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">a</span></code>.
          </p></blockquote></div></div><div class="section" title="12.27.2.&#160;use_future_t members"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__use_future_t__members"></a>12.27.2.&#160;<code class="literal">use_future_t</code> members</h4></div></div></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">OtherProtoAllocator</span><span class="special">&gt;</span> <span class="identifier">use_future_t</span><span class="special">&lt;</span><span class="identifier">OtherProtoAllocator</span><span class="special">&gt;</span>
  <span class="identifier">rebind</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">OtherProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> A <code class="computeroutput"><span class="identifier">use_future_t</span></code>
            object where <code class="computeroutput"><span class="identifier">get_allocator</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">a</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">allocator_type</span> <span class="identifier">get_allocator</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> The associated allocator object.
          </p></blockquote></div><pre class="programlisting"><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="emphasis"><em>unspecified</em></span> <span class="keyword">operator</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">const</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            Let <code class="literal">T</code> be a completion token type. Let <code class="literal">H</code>
            be a completion handler type and let <code class="literal">h</code> be an object
            of type <code class="literal">H</code>. Let <code class="literal">FD</code> be the type
            <code class="computeroutput"><span class="identifier">decay_t</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">&gt;</span></code>
            and let <code class="literal">fd</code> be an lvalue of type <code class="literal">FD</code>
            constructed with <code class="computeroutput"><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">&gt;(</span><span class="identifier">f</span><span class="special">)</span></code>. Let <code class="literal">Args</code><code class="literal">...</code>
            by the completion signature of <code class="literal">H</code> and let <code class="literal">N</code>
            be <code class="literal">sizeof</code><code class="literal">...(Args)</code>. Let <code class="literal"><span class="emphasis"><em>i</em></span></code>
            be in the range [<code class="computeroutput"><span class="number">0</span></code>,<code class="computeroutput"><span class="identifier">N</span></code>) and let <code class="literal">A<sub><span class="emphasis"><em>i</em></span></sub></code>
            be the <code class="literal"><span class="emphasis"><em>i</em></span></code>th type in <code class="computeroutput"><span class="identifier">Args</span></code>. Let <code class="literal">a<sub><span class="emphasis"><em>i</em></span></sub></code>
            be the <code class="literal"><span class="emphasis"><em>i</em></span></code>th argument associated
            with <code class="literal">A<sub><span class="emphasis"><em>i</em></span></sub></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> A completion token <code class="computeroutput"><span class="identifier">t</span></code>
            of type <code class="computeroutput"><span class="identifier">T</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Remarks:</em></span> The return type <code class="computeroutput"><span class="identifier">T</span></code>
            satisfies the <code class="computeroutput"><span class="identifier">Destructible</span></code>
            (C++Std [destructible]) and <code class="computeroutput"><span class="identifier">MoveConstructible</span></code>
            (C++Std [moveconstructible]) requirements.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            The object <code class="computeroutput"><span class="identifier">h</span></code> of type
            <code class="computeroutput"><span class="identifier">H</span></code> is an asynchronous
            provider with an associated shared state (C++Std [futures.state]). The
            effect of <code class="literal">h(<code class="literal">a<sub><span class="emphasis"><em>0</em></span></sub></code>, ...,
            <code class="literal">a<sub><span class="emphasis"><em>N-1</em></span></sub></code>)</code> is to atomically
            store the result of <code class="literal">INVOKE(fd, forward&lt;<code class="literal">A<sub><span class="emphasis"><em>0</em></span></sub></code>&gt;(<code class="literal">a<sub><span class="emphasis"><em>0</em></span></sub></code>),
            ..., forward&lt;<code class="literal">A<sub><span class="emphasis"><em>N-1</em></span></sub></code>&gt;(<code class="literal">a<sub><span class="emphasis"><em>N-1</em></span></sub></code>))</code>
            (C++Std [func.require]) in the shared state and make the shared state
            ready. If <code class="computeroutput"><span class="identifier">fd</span></code> exits via
            an exception then that exception is atomically stored in the shared state
            and the shared state is made ready.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            The implementation provides a partial specialization <code class="literal">template
            &lt;class Result, class</code><code class="literal">... Args&gt; async_result&lt;T,
            Result(Args</code><code class="literal">...)&gt;</code> such that:<br> &#8212; the
            nested typedef <code class="computeroutput"><span class="identifier">completion_handler_type</span></code>
            is a type <code class="computeroutput"><span class="identifier">H</span></code>;<br> &#8212; the
            nested typedef <code class="computeroutput"><span class="identifier">return_type</span></code>
            is <code class="literal">future&lt;result_of_t&lt;FD(decay_t&lt;Args&gt;</code><code class="literal">...)&gt;&gt;</code>;
            and<br> &#8212; when an object <code class="computeroutput"><span class="identifier">r1</span></code>
            of type <code class="literal">async_result&lt;T, Result(Args</code><code class="literal">...)&gt;</code>
            is constructed from <code class="computeroutput"><span class="identifier">h</span></code>,
            the expression <code class="computeroutput"><span class="identifier">r1</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span></code>
            returns a future with the same shared state as <code class="computeroutput"><span class="identifier">h</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            For any executor type <code class="computeroutput"><span class="identifier">E</span></code>,
            the associated object for the associator <code class="computeroutput"><span class="identifier">associated_executor</span><span class="special">&lt;</span><span class="identifier">H</span><span class="special">,</span> <span class="identifier">E</span><span class="special">&gt;</span></code> is an executor where, for function
            objects executed using the executor's <code class="computeroutput"><span class="identifier">dispatch</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">post</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">defer</span><span class="special">()</span></code> functions, any exception thrown is
            caught by a function object and stored in the associated shared state.
          </p></blockquote></div></div><div class="section" title="12.27.3.&#160;Partial class template specialization async_result for use_future_t"><div class="titlepage"><div><div><h4 class="title"><a name="classes.use_future_t_result"></a>12.27.3.&#160;Partial class template specialization <code class="literal">async_result</code>
        for <code class="literal">use_future_t</code></h4></div></div></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Result</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">use_future_t</span><span class="special">&lt;</span><span class="identifier">ProtoAllocator</span><span class="special">&gt;,</span> <span class="identifier">Result</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...)&gt;</span>
<span class="special">{</span>
  <span class="keyword">typedef</span> <span class="emphasis"><em>see below</em></span> <span class="identifier">completion_handler_type</span><span class="special">;</span>
  <span class="keyword">typedef</span> <span class="emphasis"><em>see below</em></span> <span class="identifier">return_type</span><span class="special">;</span>

  <span class="keyword">explicit</span> <span class="identifier">async_result</span><span class="special">(</span><span class="identifier">completion_handler_type</span><span class="special">&amp;</span> <span class="identifier">h</span><span class="special">);</span>
  <span class="identifier">async_result</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">async_result</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
  <span class="identifier">async_result</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">async_result</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>

  <span class="identifier">return_type</span> <span class="identifier">get</span><span class="special">();</span>
<span class="special">};</span>
</pre><p>
          Let <code class="computeroutput"><span class="identifier">R</span></code> be the type <code class="computeroutput"><span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">use_future_t</span><span class="special">&lt;</span><span class="identifier">ProtoAllocator</span><span class="special">&gt;,</span>
          <span class="identifier">Result</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...)&gt;</span></code>.
          Let <code class="computeroutput"><span class="identifier">F</span></code> be the nested function
          object type <code class="computeroutput"><span class="identifier">R</span><span class="special">::</span><span class="identifier">completion_handler_type</span></code>.
        </p><p>
          An object <code class="computeroutput"><span class="identifier">t1</span></code> of type <code class="computeroutput"><span class="identifier">F</span></code> is an asynchronous provider with an
          associated shared state (C++Std [futures.state]). The type <code class="computeroutput"><span class="identifier">F</span></code> provides <code class="computeroutput"><span class="identifier">F</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span></code> such that the expression <code class="computeroutput"><span class="identifier">t1</span><span class="special">(</span><span class="identifier">declval</span><span class="special">&lt;</span><span class="identifier">Args</span><span class="special">&gt;()...)</span></code> is well formed.
        </p><p>
          The implementation specializes <code class="computeroutput"><span class="identifier">associated_executor</span></code>
          for <code class="computeroutput"><span class="identifier">F</span></code>. For function objects
          executed using the associated executor's <code class="computeroutput"><span class="identifier">dispatch</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">post</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">defer</span><span class="special">()</span></code> functions, any exception thrown is caught
          by the executor and stored in the associated shared state.
        </p><p>
          For any executor type <code class="computeroutput"><span class="identifier">E</span></code>,
          the associated object for the associator <code class="computeroutput"><span class="identifier">associated_executor</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">,</span> <span class="identifier">E</span><span class="special">&gt;</span></code>
          is an executor where, for function objects executed using the executor's
          <code class="computeroutput"><span class="identifier">dispatch</span><span class="special">()</span></code>,
          <code class="computeroutput"><span class="identifier">post</span><span class="special">()</span></code>
          or <code class="computeroutput"><span class="identifier">defer</span><span class="special">()</span></code>
          functions, any exception thrown by a function object is caught by the executor
          and stored in the associated shared state.
        </p><p>
          When an object <code class="computeroutput"><span class="identifier">r1</span></code> of type
          <code class="computeroutput"><span class="identifier">R</span></code> is constructed from
          <code class="computeroutput"><span class="identifier">t1</span></code>, the expression <code class="computeroutput"><span class="identifier">r1</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span></code> returns a future with the same shared
          state as <code class="computeroutput"><span class="identifier">t1</span></code>.
        </p><p>
          The type of <code class="computeroutput"><span class="identifier">R</span><span class="special">::</span><span class="identifier">return_type</span></code> and the effects of <code class="computeroutput"><span class="identifier">F</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span></code> are defined in the table below. After
          establishing these effects, <code class="computeroutput"><span class="identifier">F</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span></code> makes the shared state ready. In this
          table, <code class="literal">N</code> is the value of <code class="computeroutput"><span class="keyword">sizeof</span><span class="special">...(</span><span class="identifier">Args</span><span class="special">)</span></code>; let <code class="literal"><span class="emphasis"><em>i</em></span></code>
          be in the range [<code class="computeroutput"><span class="number">0</span></code>,<code class="computeroutput"><span class="identifier">N</span></code>) and let <code class="literal">T<sub><span class="emphasis"><em>i</em></span></sub></code>
          be the <code class="literal"><span class="emphasis"><em>i</em></span></code>th type in <code class="computeroutput"><span class="identifier">Args</span></code>; let <code class="literal">U<sub><span class="emphasis"><em>i</em></span></sub></code>
          be <code class="literal">decay_t&lt;T<sub><span class="emphasis"><em>i</em></span></sub>&gt;</code> for each type
          <code class="literal">T<sub><span class="emphasis"><em>i</em></span></sub></code> in <code class="computeroutput"><span class="identifier">Args</span></code>;
          let <code class="literal">A<sub><span class="emphasis"><em>i</em></span></sub></code> be the deduced type of the
          <code class="literal"><span class="emphasis"><em>i</em></span></code>th argument to <code class="computeroutput"><span class="identifier">F</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span></code>; and let <code class="literal">a<sub><span class="emphasis"><em>i</em></span></sub></code>
          be the <code class="literal"><span class="emphasis"><em>i</em></span></code>th argument to <code class="computeroutput"><span class="identifier">F</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span></code>.
        </p><div class="table"><a name="classes.proposed_text.use_future_t.use_future_t_result.t0"></a><p class="title"><b>Table&#160;9.&#160;async_result&lt;use_future_t&lt;ProtoAllocator&gt;, Result(Args...)&gt;
          semantics</b></p><div class="table-contents"><table class="table" summary="async_result&lt;use_future_t&lt;ProtoAllocator&gt;, Result(Args...)&gt;
          semantics"><colgroup><col><col><col><col></colgroup><thead><tr><th>
                  <p>
                    <code class="literal">N</code>
                  </p>
                </th><th>
                  <p>
                    <code class="literal">U<sub><span class="emphasis"><em>0</em></span></sub></code>
                  </p>
                </th><th>
                  <p>
                    <code class="computeroutput"><span class="identifier">R</span><span class="special">::</span><span class="identifier">return_type</span></code>
                  </p>
                </th><th>
                  <p>
                    <code class="computeroutput"><span class="identifier">F</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span></code>
                    effects
                  </p>
                </th></tr></thead><tbody><tr><td>
                  <p>
                    0
                  </p>
                </td><td>
                </td><td>
                  <p>
                    <code class="literal">future&lt;void&gt;</code>
                  </p>
                </td><td>
                  <p>
                    None.
                  </p>
                </td></tr><tr><td>
                  <p>
                    1
                  </p>
                </td><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">error_code</span></code>
                  </p>
                </td><td>
                  <p>
                    <code class="literal">future&lt;void&gt;</code>
                  </p>
                </td><td>
                  <p>
                    If <code class="literal">a<sub><span class="emphasis"><em>0</em></span></sub></code> evaluates to <code class="computeroutput"><span class="keyword">true</span></code>, atomically stores the exception
                    pointer produced by <code class="literal">make_exception_ptr(system_error(a<sub><span class="emphasis"><em>0</em></span></sub>))</code>
                    in the shared state.
                  </p>
                </td></tr><tr><td>
                  <p>
                    1
                  </p>
                </td><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">exception_ptr</span></code>
                  </p>
                </td><td>
                  <p>
                    <code class="literal">future&lt;void&gt;</code>
                  </p>
                </td><td>
                  <p>
                    If <code class="literal">a<sub><span class="emphasis"><em>0</em></span></sub></code> is non-null, atomically
                    stores the exception pointer <code class="literal">a<sub><span class="emphasis"><em>0</em></span></sub></code>
                    in the shared state.
                  </p>
                </td></tr><tr><td>
                  <p>
                    1
                  </p>
                </td><td>
                  <p>
                    all other types
                  </p>
                </td><td>
                  <p>
                    <code class="literal">future&lt;U<sub><span class="emphasis"><em>0</em></span></sub>&gt;</code>
                  </p>
                </td><td>
                  <p>
                    Atomically stores <code class="literal">forward&lt;A<sub><span class="emphasis"><em>0</em></span></sub>&gt;(a<sub><span class="emphasis"><em>0</em></span></sub>)</code>
                    in the shared state.
                  </p>
                </td></tr><tr><td>
                  <p>
                    2
                  </p>
                </td><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">error_code</span></code>
                  </p>
                </td><td>
                  <p>
                    <code class="literal">future&lt;U<sub><span class="emphasis"><em>1</em></span></sub>&gt;</code>
                  </p>
                </td><td>
                  <p>
                    If <code class="literal">a<sub><span class="emphasis"><em>0</em></span></sub></code> evaluates to <code class="computeroutput"><span class="keyword">true</span></code>, atomically stores the exception
                    pointer produced by <code class="literal">make_exception_ptr(system_error(a<sub><span class="emphasis"><em>0</em></span></sub>))</code>
                    in the shared state; otherwise, atomically stores <code class="literal">forward&lt;A<sub><span class="emphasis"><em>1</em></span></sub>&gt;(a<sub><span class="emphasis"><em>1</em></span></sub>)</code>
                    in the shared state.
                  </p>
                </td></tr><tr><td>
                  <p>
                    2
                  </p>
                </td><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">exception_ptr</span></code>
                  </p>
                </td><td>
                  <p>
                    <code class="literal">future&lt;U<sub><span class="emphasis"><em>1</em></span></sub>&gt;</code>
                  </p>
                </td><td>
                  <p>
                    If <code class="literal">a<sub><span class="emphasis"><em>0</em></span></sub></code> is non-null, atomically
                    stores the exception pointer in the shared state; otherwise,
                    atomically stores <code class="literal">forward&lt;A<sub><span class="emphasis"><em>1</em></span></sub>&gt;(a<sub><span class="emphasis"><em>1</em></span></sub>)</code>
                    in the shared state.
                  </p>
                </td></tr><tr><td>
                  <p>
                    2
                  </p>
                </td><td>
                  <p>
                    all other types
                  </p>
                </td><td>
                  <p>
                    <code class="literal">future&lt;tuple&lt;U<sub><span class="emphasis"><em>0</em></span></sub>,U<sub><span class="emphasis"><em>1</em></span></sub>&gt;&gt;</code>
                  </p>
                </td><td>
                  <p>
                    Atomically stores <code class="literal">forward_as_tuple&lt;A<sub><span class="emphasis"><em>0</em></span></sub>,A<sub><span class="emphasis"><em>1</em></span></sub>&gt;(a<sub><span class="emphasis"><em>0</em></span></sub>,a<sub><span class="emphasis"><em>1</em></span></sub>)</code>
                    in the shared state.
                  </p>
                </td></tr><tr><td>
                  <p>
                    &gt;2
                  </p>
                </td><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">error_code</span></code>
                  </p>
                </td><td>
                  <p>
                    <code class="literal">future&lt;tuple&lt;U<sub><span class="emphasis"><em>1</em></span></sub>,...,U<sub><span class="emphasis"><em>N-1</em></span></sub>&gt;&gt;</code>
                  </p>
                </td><td>
                  <p>
                    If <code class="literal">a<sub><span class="emphasis"><em>0</em></span></sub></code> evaluates to <code class="computeroutput"><span class="keyword">true</span></code>, atomically stores the exception
                    pointer produced by <code class="literal">make_exception_ptr(system_error(a<sub><span class="emphasis"><em>0</em></span></sub>))</code>
                    in the shared state; otherwise, atomically stores <code class="literal">forward_as_tuple&lt;A<sub><span class="emphasis"><em>1</em></span></sub>,...,A<sub><span class="emphasis"><em>N-1</em></span></sub>)&gt;(a<sub><span class="emphasis"><em>1</em></span></sub>,...,a<sub><span class="emphasis"><em>N-1</em></span></sub>)</code>
                    in the shared state.
                  </p>
                </td></tr><tr><td>
                  <p>
                    &gt;2
                  </p>
                </td><td>
                  <p>
                    <code class="computeroutput"><span class="identifier">exception_ptr</span></code>
                  </p>
                </td><td>
                  <p>
                    <code class="literal">future&lt;tuple&lt;U<sub><span class="emphasis"><em>1</em></span></sub>,...,U<sub><span class="emphasis"><em>N-1</em></span></sub>&gt;&gt;</code>
                  </p>
                </td><td>
                  <p>
                    If <code class="literal">a<sub><span class="emphasis"><em>0</em></span></sub></code> is non-null, atomically
                    stores the exception pointer in the shared state; otherwise,
                    atomically stores <code class="literal">forward_as_tuple&lt;A<sub><span class="emphasis"><em>1</em></span></sub>,...,A<sub><span class="emphasis"><em>N-1</em></span></sub>&gt;(a<sub><span class="emphasis"><em>1</em></span></sub>,...,a<sub><span class="emphasis"><em>N-1</em></span></sub>)</code>
                    in the shared state.
                  </p>
                </td></tr><tr><td>
                  <p>
                    &gt;2
                  </p>
                </td><td>
                  <p>
                    all other types
                  </p>
                </td><td>
                  <p>
                    <code class="literal">future&lt;tuple&lt;U<sub><span class="emphasis"><em>0</em></span></sub>,...,U<sub><span class="emphasis"><em>N-1</em></span></sub>&gt;&gt;</code>
                  </p>
                </td><td>
                  <p>
                    Atomically stores <code class="literal">forward_as_tuple&lt;A<sub><span class="emphasis"><em>0</em></span></sub>,...,A<sub><span class="emphasis"><em>N-1</em></span></sub>&gt;(a<sub><span class="emphasis"><em>0</em></span></sub>,...,a<sub><span class="emphasis"><em>N-1</em></span></sub>)</code>
                    in the shared state.
                  </p>
                </td></tr></tbody></table></div></div><br class="table-break"></div></div><div class="section" title="12.28.&#160;Partial class template specialization async_result for packaged_task"><div class="titlepage"><div><div><h3 class="title"><a name="classes.async_result_packaged_task"></a>12.28.&#160;Partial class template specialization <code class="literal">async_result</code>
      for <code class="literal">packaged_task</code></h3></div></div></div><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Result</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Signature</span><span class="special">&gt;</span>
  <span class="keyword">class</span> <span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">packaged_task</span><span class="special">&lt;</span><span class="identifier">Result</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...)&gt;,</span> <span class="identifier">Signature</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">packaged_task</span><span class="special">&lt;</span><span class="identifier">Result</span><span class="special">(</span><span class="identifier">Args</span><span class="special">...)&gt;</span> <span class="identifier">completion_handler_type</span><span class="special">;</span>
    <span class="keyword">typedef</span> <span class="identifier">future</span><span class="special">&lt;</span><span class="identifier">Result</span><span class="special">&gt;</span> <span class="identifier">return_type</span><span class="special">;</span>

    <span class="keyword">explicit</span> <span class="identifier">async_result</span><span class="special">(</span><span class="identifier">completion_handler_type</span><span class="special">&amp;</span> <span class="identifier">h</span><span class="special">);</span>
    <span class="identifier">async_result</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">async_result</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
    <span class="identifier">async_result</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">async_result</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>

    <span class="identifier">return_type</span> <span class="identifier">get</span><span class="special">();</span>

  <span class="keyword">private</span><span class="special">:</span>
    <span class="identifier">return_type</span> <span class="identifier">future_</span><span class="special">;</span> <span class="comment">// <span class="emphasis"><em>exposition only</em></span></span>
  <span class="special">};</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>

<span class="keyword">explicit</span> <span class="identifier">async_result</span><span class="special">(</span><span class="identifier">completion_handler_type</span><span class="special">&amp;</span> <span class="identifier">h</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Effects:</em></span> Initializes <code class="computeroutput"><span class="identifier">future_</span></code>
          with <code class="computeroutput"><span class="identifier">h</span><span class="special">.</span><span class="identifier">get_future</span><span class="special">()</span></code>.
        </p></blockquote></div><pre class="programlisting"><span class="identifier">return_type</span> <span class="identifier">get</span><span class="special">();</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
          <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">future_</span><span class="special">)</span></code>.
        </p></blockquote></div></div><div class="section" title="12.29.&#160;Header &lt;experimental/thread_pool&gt; synopsis"><div class="titlepage"><div><div><h3 class="title"><a name="headers.thread_pool"></a>12.29.&#160;Header <code class="literal">&lt;experimental/thread_pool&gt;</code> synopsis</h3></div></div></div><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">class</span> <a class="link" href="#classes.thread_pool" title="12.30.&#160;Class thread_pool">thread_pool</a><span class="special">;</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>
</pre></div><div class="section" title="12.30.&#160;Class thread_pool"><div class="titlepage"><div><div><h3 class="title"><a name="classes.thread_pool"></a>12.30.&#160;Class <code class="literal">thread_pool</code></h3></div></div></div><p>
        Class <code class="computeroutput"><span class="identifier">thread_pool</span></code> implements
        a fixed-size pool of threads.
      </p><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">class</span> <span class="identifier">thread_pool</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">execution_context</span>
  <span class="special">{</span>
  <span class="keyword">public</span><span class="special">:</span>
    <span class="comment">// types:</span>

    <span class="keyword">class</span> <a class="link" href="#classes.thread_pool__executor_type" title="12.31.&#160;Class thread_pool::executor_type">executor_type</a><span class="special">;</span>

    <span class="comment">// construct / copy / destroy:</span>

    <span class="identifier">thread_pool</span><span class="special">();</span>
    <span class="keyword">explicit</span> <span class="identifier">thread_pool</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">num_threads</span><span class="special">);</span>
    <span class="identifier">thread_pool</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">thread_pool</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
    <span class="identifier">thread_pool</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">thread_pool</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
    <span class="special">~</span><span class="identifier">thread_pool</span><span class="special">();</span>

    <span class="comment">// thread_pool operations:</span>

    <span class="identifier">executor_type</span> <span class="identifier">get_executor</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="keyword">void</span> <span class="identifier">stop</span><span class="special">();</span>

    <span class="keyword">void</span> <span class="identifier">join</span><span class="special">();</span>
  <span class="special">};</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>
</pre><p>
        The class <code class="computeroutput"><span class="identifier">thread_pool</span></code> satisfies
        the <a class="link" href="#requirements.execution_context" title="12.3.2.&#160;Execution context requirements">ExecutionContext type
        requirements</a>.
      </p><p>
        For an object of type <code class="computeroutput"><span class="identifier">thread_pool</span></code>,
        <span class="emphasis"><em>outstanding work</em></span> is defined as the sum of:
      </p><p>
        &#8212; the total number of calls to the <code class="computeroutput"><span class="identifier">on_work_started</span></code>
        function, less the total number of calls to the <code class="computeroutput"><span class="identifier">on_work_finished</span></code>
        function, to any executor of the <code class="computeroutput"><span class="identifier">thread_pool</span></code>.
      </p><p>
        &#8212; the number of function objects that have been added to the <code class="computeroutput"><span class="identifier">thread_pool</span></code> via the <code class="computeroutput"><span class="identifier">thread_pool</span></code>
        executor, but not yet executed; and
      </p><p>
        &#8212; the number of function objects that are currently being executed by the
        <code class="computeroutput"><span class="identifier">thread_pool</span></code>.
      </p><p>
        The <code class="computeroutput"><span class="identifier">thread_pool</span></code> member functions
        <code class="computeroutput"><span class="identifier">get_executor</span></code>, <code class="computeroutput"><span class="identifier">stop</span></code>, and <code class="computeroutput"><span class="identifier">join</span></code>,
        and the <code class="computeroutput"><span class="identifier">thread_pool</span><span class="special">::</span><span class="identifier">executor_type</span></code> copy constructors, member
        functions and comparison operators, do not introduce data races as a result
        of concurrent calls to those functions from different threads of execution.
      </p><div class="section" title="12.30.1.&#160;thread_pool members"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__thread_pool__members"></a>12.30.1.&#160;<code class="literal">thread_pool</code> members</h4></div></div></div><pre class="programlisting"><span class="identifier">thread_pool</span><span class="special">();</span>
<span class="keyword">explicit</span> <span class="identifier">thread_pool</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">num_threads</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Creates an object of class <code class="computeroutput"><span class="identifier">thread_pool</span></code> containing a number of
            threads of execution, each represented by a <code class="computeroutput"><span class="identifier">thread</span></code>
            object. If specified, the number of threads in the pool is <code class="computeroutput"><span class="identifier">num_threads</span></code>. Otherwise, the number
            of threads in the pool is implementation-defined. [<span class="emphasis"><em>Note:</em></span>
            A suggested value for the implementation-defined number of threads is
            <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span><span class="special">::</span><span class="identifier">hardware_concurrency</span><span class="special">()</span>
            <span class="special">*</span> <span class="number">2</span></code>.
            &#8212;<span class="emphasis"><em>end note</em></span>]
          </p></blockquote></div><pre class="programlisting"><span class="special">~</span><span class="identifier">thread_pool</span><span class="special">();</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Destroys an object of class <code class="computeroutput"><span class="identifier">thread_pool</span></code>. Performs <code class="computeroutput"><span class="identifier">stop</span><span class="special">()</span></code>
            followed by <code class="computeroutput"><span class="identifier">join</span><span class="special">()</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">executor_type</span> <span class="identifier">get_executor</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> An executor that may be used for submitting
            function objects to the <code class="computeroutput"><span class="identifier">thread_pool</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">stop</span><span class="special">();</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Signals the threads in the pool to complete
            as soon as possible. If a thread is currently executing a function object,
            the thread will exit only after completion of that function object. The
            call to <code class="computeroutput"><span class="identifier">stop</span><span class="special">()</span></code>
            returns without waiting for the threads to complete.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">join</span><span class="special">();</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> If not already stopped, signals the threads
            in the pool to exit once the outstanding work is <code class="computeroutput"><span class="number">0</span></code>.
            Blocks the calling thread (C++Std [defns.block]) until all threads in
            the pool have completed.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Synchronization:</em></span> The completion of each thread in
            the pool synchronizes with (C++Std [intro.multithread]) the corresponding
            successful <code class="computeroutput"><span class="identifier">join</span><span class="special">()</span></code>
            return.
          </p></blockquote></div></div></div><div class="section" title="12.31.&#160;Class thread_pool::executor_type"><div class="titlepage"><div><div><h3 class="title"><a name="classes.thread_pool__executor_type"></a>12.31.&#160;Class <code class="literal">thread_pool::executor_type</code></h3></div></div></div><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">class</span> <span class="identifier">thread_pool</span><span class="special">::</span><span class="identifier">executor_type</span>
  <span class="special">{</span>
  <span class="keyword">public</span><span class="special">:</span>
    <span class="comment">// construct / copy / destroy:</span>

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

    <span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">executor_type</span><span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="comment">// executor operations:</span>

    <span class="keyword">bool</span> <span class="identifier">running_in_this_thread</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="identifier">thread_pool</span><span class="special">&amp;</span> <span class="identifier">context</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="keyword">void</span> <span class="identifier">on_work_started</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">void</span> <span class="identifier">on_work_finished</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
      <span class="keyword">void</span> <span class="identifier">dispatch</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
      <span class="keyword">void</span> <span class="identifier">post</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
      <span class="keyword">void</span> <span class="identifier">defer</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
  <span class="special">};</span>

  <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">thread_pool</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span>
                  <span class="keyword">const</span> <span class="identifier">thread_pool</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="keyword">const</span> <span class="identifier">thread_pool</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span>
                  <span class="keyword">const</span> <span class="identifier">thread_pool</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>

  <span class="keyword">template</span><span class="special">&lt;&gt;</span> <span class="keyword">struct</span> <span class="identifier">is_executor</span><span class="special">&lt;</span><span class="identifier">thread_pool</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&gt;</span> <span class="special">:</span> <span class="identifier">true_type</span> <span class="special">{};</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>
</pre><p>
        <code class="computeroutput"><span class="identifier">thread_pool</span><span class="special">::</span><span class="identifier">executor_type</span></code> is a type satisfying <a class="link" href="#requirements.executor" title="12.3.3.&#160;Executor requirements">Executor requirements</a>. Objects of
        type <code class="computeroutput"><span class="identifier">thread_pool</span><span class="special">::</span><span class="identifier">executor_type</span></code> are associated with a <code class="computeroutput"><span class="identifier">thread_pool</span></code>, and function objects submitted
        using the <code class="computeroutput"><span class="identifier">dispatch</span></code>, <code class="computeroutput"><span class="identifier">post</span></code>, or <code class="computeroutput"><span class="identifier">defer</span></code>
        member functions will be executed by the <code class="computeroutput"><span class="identifier">thread_pool</span></code>.]
      </p><div class="section" title="12.31.1.&#160;thread_pool::executor_type constructors"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__thread_pool__executor_type__constructors"></a>12.31.1.&#160;<code class="literal">thread_pool::executor_type</code> constructors</h4></div></div></div><pre class="programlisting"><span class="identifier">executor_type</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span> <span class="special">==</span> <span class="identifier">other</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">executor_type</span><span class="special">(</span><span class="identifier">executor_type</span><span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is equal to the prior value of <code class="computeroutput"><span class="identifier">other</span></code>.
          </p></blockquote></div></div><div class="section" title="12.31.2.&#160;thread_pool::executor_type assignment"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__thread_pool__executor_type__assignment"></a>12.31.2.&#160;<code class="literal">thread_pool::executor_type</code> assignment</h4></div></div></div><pre class="programlisting"><span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span> <span class="special">==</span> <span class="identifier">other</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">executor_type</span><span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is equal to the prior value of <code class="computeroutput"><span class="identifier">other</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
          </p></blockquote></div></div><div class="section" title="12.31.3.&#160;thread_pool::executor_type operations"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__thread_pool__executor_type__operations"></a>12.31.3.&#160;<code class="literal">thread_pool::executor_type</code> operations</h4></div></div></div><pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">running_in_this_thread</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="keyword">true</span></code>
            if the current thread of execution is calling a run function of the associated
            <code class="computeroutput"><span class="identifier">thread_pool</span></code> object. [<span class="emphasis"><em>Note:</em></span>
            That is, the current thread of execution's call chain includes a run
            function. &#8212;<span class="emphasis"><em>end note</em></span>]
          </p></blockquote></div><pre class="programlisting"><span class="identifier">thread_pool</span><span class="special">&amp;</span> <span class="identifier">context</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> A reference to the associated <code class="computeroutput"><span class="identifier">thread_pool</span></code> object.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">on_work_started</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Increment the count of outstanding work
            associated with the <code class="computeroutput"><span class="identifier">thread_pool</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">on_work_finished</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Decrement the count of outstanding work
            associated with the <code class="computeroutput"><span class="identifier">thread_pool</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
  <span class="keyword">void</span> <span class="identifier">dispatch</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> If <code class="computeroutput"><span class="identifier">running_in_this_thread</span><span class="special">()</span></code> is <code class="computeroutput"><span class="keyword">true</span></code>,
            calls <code class="literal"><span class="emphasis"><em>DECAY_COPY</em></span></code><code class="computeroutput"><span class="special">(</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Func</span><span class="special">&gt;(</span><span class="identifier">f</span><span class="special">))()</span></code> (C++Std [thread.decaycopy]). [<span class="emphasis"><em>Note:</em></span>
            If <code class="computeroutput"><span class="identifier">f</span></code> exits via an exception,
            the exception propagates to the caller of <code class="computeroutput"><span class="identifier">dispatch</span><span class="special">()</span></code>. &#8212;<span class="emphasis"><em>end note</em></span>] Otherwise,
            calls <code class="computeroutput"><span class="identifier">post</span><span class="special">(</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Func</span><span class="special">&gt;(</span><span class="identifier">f</span><span class="special">),</span> <span class="identifier">a</span><span class="special">)</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
  <span class="keyword">void</span> <span class="identifier">post</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Adds <code class="computeroutput"><span class="identifier">f</span></code>
            to the <code class="computeroutput"><span class="identifier">thread_pool</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
  <span class="keyword">void</span> <span class="identifier">defer</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Adds <code class="computeroutput"><span class="identifier">f</span></code>
            to the <code class="computeroutput"><span class="identifier">thread_pool</span></code>.
          </p></blockquote></div></div><div class="section" title="12.31.4.&#160;thread_pool::executor_type comparisons"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__thread_pool__executor_type__comparisons"></a>12.31.4.&#160;<code class="literal">thread_pool::executor_type</code> comparisons</h4></div></div></div><pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">thread_pool</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span>
                <span class="keyword">const</span> <span class="identifier">thread_pool</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">addressof</span><span class="special">(</span><span class="identifier">a</span><span class="special">.</span><span class="identifier">context</span><span class="special">())</span> <span class="special">==</span> <span class="identifier">addressof</span><span class="special">(</span><span class="identifier">b</span><span class="special">.</span><span class="identifier">context</span><span class="special">())</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="keyword">const</span> <span class="identifier">thread_pool</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span>
                <span class="keyword">const</span> <span class="identifier">thread_pool</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="special">!(</span><span class="identifier">a</span> <span class="special">==</span> <span class="identifier">b</span><span class="special">)</span></code>.
          </p></blockquote></div></div></div><div class="section" title="12.32.&#160;Header &lt;experimental/loop_scheduler&gt; synopsis"><div class="titlepage"><div><div><h3 class="title"><a name="headers.loop_scheduler"></a>12.32.&#160;Header <code class="literal">&lt;experimental/loop_scheduler&gt;</code> synopsis</h3></div></div></div><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">class</span> <a class="link" href="#classes.loop_scheduler" title="12.33.&#160;Class loop_scheduler">loop_scheduler</a><span class="special">;</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>
</pre></div><div class="section" title="12.33.&#160;Class loop_scheduler"><div class="titlepage"><div><div><h3 class="title"><a name="classes.loop_scheduler"></a>12.33.&#160;Class <code class="literal">loop_scheduler</code></h3></div></div></div><p>
        Class <code class="computeroutput"><span class="identifier">loop_scheduler</span></code> implements
        a pool of threads where existing threads are assigned to the pool by the
        program.
      </p><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">class</span> <span class="identifier">loop_scheduler</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">execution_context</span>
  <span class="special">{</span>
  <span class="keyword">public</span><span class="special">:</span>
    <span class="comment">// types:</span>

    <span class="keyword">class</span> <a class="link" href="#classes.loop_scheduler__executor_type" title="12.34.&#160;Class loop_scheduler::executor_type">executor_type</a><span class="special">;</span>
    <span class="keyword">typedef</span> <span class="emphasis"><em>implementation defined</em></span> <span class="identifier">count_type</span><span class="special">;</span>

    <span class="comment">// construct / copy / destroy:</span>

    <span class="identifier">loop_scheduler</span><span class="special">();</span>
    <span class="keyword">explicit</span> <span class="identifier">loop_scheduler</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">concurrency_hint</span><span class="special">);</span>
    <span class="identifier">loop_scheduler</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">loop_scheduler</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
    <span class="identifier">loop_scheduler</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">loop_scheduler</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>

    <span class="comment">// loop_scheduler operations:</span>

    <span class="identifier">executor_type</span> <span class="identifier">get_executor</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="identifier">count_type</span> <span class="identifier">run</span><span class="special">();</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Period</span><span class="special">&gt;</span>
      <span class="identifier">count_type</span> <span class="identifier">run_for</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span><span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span><span class="special">&gt;&amp;</span> <span class="identifier">rel_time</span><span class="special">);</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Duration</span><span class="special">&gt;</span>
      <span class="identifier">count_type</span> <span class="identifier">run_until</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span><span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span><span class="special">&gt;&amp;</span> <span class="identifier">abs_time</span><span class="special">);</span>

    <span class="identifier">count_type</span> <span class="identifier">run_one</span><span class="special">();</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Period</span><span class="special">&gt;</span>
      <span class="identifier">count_type</span> <span class="identifier">run_one_for</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span><span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span><span class="special">&gt;&amp;</span> <span class="identifier">rel_time</span><span class="special">);</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Duration</span><span class="special">&gt;</span>
      <span class="identifier">count_type</span> <span class="identifier">run_one_until</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span><span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span><span class="special">&gt;&amp;</span> <span class="identifier">abs_time</span><span class="special">);</span>

    <span class="identifier">count_type</span> <span class="identifier">poll</span><span class="special">();</span>

    <span class="identifier">count_type</span> <span class="identifier">poll_one</span><span class="special">();</span>

    <span class="keyword">void</span> <span class="identifier">stop</span><span class="special">();</span>

    <span class="keyword">bool</span> <span class="identifier">stopped</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="keyword">void</span> <span class="identifier">restart</span><span class="special">();</span>
  <span class="special">};</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>
</pre><p>
        The class <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>
        satisfies the <a class="link" href="#requirements.execution_context" title="12.3.2.&#160;Execution context requirements">ExecutionContext
        type requirements</a>.
      </p><p>
        <code class="computeroutput"><span class="identifier">count_type</span></code> is an implementation-defined
        unsigned integral type of at least 32 bits.
      </p><p>
        The <code class="computeroutput"><span class="identifier">loop_scheduler</span></code> member
        functions <code class="computeroutput"><span class="identifier">run</span></code>, <code class="computeroutput"><span class="identifier">run_for</span></code>, <code class="computeroutput"><span class="identifier">run_until</span></code>,
        <code class="computeroutput"><span class="identifier">run_one</span></code>, <code class="computeroutput"><span class="identifier">run_one_for</span></code>,
        <code class="computeroutput"><span class="identifier">run_one_until</span></code>, <code class="computeroutput"><span class="identifier">poll</span></code>, and <code class="computeroutput"><span class="identifier">poll_one</span></code>
        are collectively referred to as the <span class="emphasis"><em>run functions</em></span>.
      </p><p>
        For an object of type <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>,
        <span class="emphasis"><em>outstanding work</em></span> is defined as the sum of:
      </p><p>
        &#8212; the total number of calls to the <code class="computeroutput"><span class="identifier">on_work_started</span></code>
        function, less the total number of calls to the <code class="computeroutput"><span class="identifier">on_work_finished</span></code>
        function, to any executor of the <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>.
      </p><p>
        &#8212; the number of function objects that have been added to the <code class="computeroutput"><span class="identifier">loop_scheduler</span></code> via any executor of the
        <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>, but not yet
        executed; and
      </p><p>
        &#8212; the number of function objects that are currently being executed by the
        <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>.
      </p><p>
        If at any time the outstanding work falls to <code class="computeroutput"><span class="number">0</span></code>,
        the <code class="computeroutput"><span class="identifier">loop_scheduler</span></code> is stopped
        as if by <code class="computeroutput"><span class="identifier">stop</span><span class="special">()</span></code>.
      </p><p>
        The <code class="computeroutput"><span class="identifier">loop_scheduler</span></code> member
        functions <code class="computeroutput"><span class="identifier">get_executor</span></code>,
        <code class="computeroutput"><span class="identifier">stop</span></code>, and <code class="computeroutput"><span class="identifier">stopped</span></code>,
        the run functions, and the <code class="computeroutput"><span class="identifier">loop_scheduler</span><span class="special">::</span><span class="identifier">executor_type</span></code>
        copy constructors, member functions and comparison operators, do not introduce
        data races as a result of concurrent calls to those functions from different
        threads of execution. [<span class="emphasis"><em>Note:</em></span> The <code class="computeroutput"><span class="identifier">restart</span></code>
        member function is excluded from these thread safety requirements. &#8212;<span class="emphasis"><em>end
        note</em></span>]
      </p><div class="section" title="12.33.1.&#160;loop_scheduler members"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__loop_scheduler__members"></a>12.33.1.&#160;<code class="literal">loop_scheduler</code> members</h4></div></div></div><pre class="programlisting"><span class="identifier">loop_scheduler</span><span class="special">();</span>
<span class="keyword">explicit</span> <span class="identifier">loop_scheduler</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">concurrency_hint</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Creates an object of class <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Remarks:</em></span> The <code class="computeroutput"><span class="identifier">concurrency_hint</span></code>
            parameter is a suggestion to the implementation on the number of threads
            that should execute function objects.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">executor_type</span> <span class="identifier">get_executor</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> An executor that may be used for submitting
            function objects to the <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">count_type</span> <span class="identifier">run</span><span class="special">();</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Requires:</em></span> Must not be called from a thread that
            is currently calling a run function.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Equivalent to:
</p><pre class="programlisting"><span class="identifier">count_type</span> <span class="identifier">n</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">run_one</span><span class="special">())</span>
  <span class="keyword">if</span> <span class="special">(</span><span class="identifier">n</span> <span class="special">!=</span> <span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">count_type</span><span class="special">&gt;::</span><span class="identifier">max</span><span class="special">())</span>
    <span class="special">++</span><span class="identifier">n</span><span class="special">;</span>
</pre><p>
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">n</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Period</span><span class="special">&gt;</span>
  <span class="identifier">count_type</span> <span class="identifier">run_for</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span><span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span><span class="special">&gt;&amp;</span> <span class="identifier">rel_time</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Equivalent to:
</p><pre class="programlisting"><span class="keyword">return</span> <span class="identifier">run_until</span><span class="special">(</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">steady_clock</span><span class="special">::</span><span class="identifier">now</span><span class="special">()</span> <span class="special">+</span> <span class="identifier">rel_time</span><span class="special">);</span>
</pre><p>
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Duration</span><span class="special">&gt;</span>
  <span class="identifier">count_type</span> <span class="identifier">run_until</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span><span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span><span class="special">&gt;&amp;</span> <span class="identifier">abs_time</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Equivalent to:
</p><pre class="programlisting"><span class="identifier">count_type</span> <span class="identifier">n</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">run_one_until</span><span class="special">(</span><span class="identifier">abs_time</span><span class="special">))</span>
  <span class="keyword">if</span> <span class="special">(</span><span class="identifier">n</span> <span class="special">!=</span> <span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">count_type</span><span class="special">&gt;::</span><span class="identifier">max</span><span class="special">())</span>
    <span class="special">++</span><span class="identifier">n</span><span class="special">;</span>
</pre><p>
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">n</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">count_type</span> <span class="identifier">run_one</span><span class="special">();</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Requires:</em></span> Must not be called from a thread that
            is currently calling a run function.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> If the <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>
            object has no outstanding work, performs <code class="computeroutput"><span class="identifier">stop</span><span class="special">()</span></code>. Otherwise, blocks while the loop_scheduler
            has outstanding work, or until the <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>
            is stopped, or until one function object has been executed.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            If an executed function object throws an exception, the exception propagates
            to the caller of <code class="computeroutput"><span class="identifier">run_one</span><span class="special">()</span></code>. The <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>
            state is as if the function object had returned normally.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="number">1</span></code>
            if a function object was executed, otherwise <code class="computeroutput"><span class="number">0</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Notes:</em></span> This function may invoke additional function
            objects through nested calls to the <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>
            executor's <code class="computeroutput"><span class="identifier">dispatch</span></code> member
            function. These do not count towards the return value.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Period</span><span class="special">&gt;</span>
  <span class="identifier">count_type</span> <span class="identifier">run_one_for</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span><span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span><span class="special">&gt;&amp;</span> <span class="identifier">rel_time</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Equivalent to:
</p><pre class="programlisting"><span class="keyword">return</span> <span class="identifier">run_one_until</span><span class="special">(</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">steady_clock</span><span class="special">::</span><span class="identifier">now</span><span class="special">()</span> <span class="special">+</span> <span class="identifier">rel_time</span><span class="special">);</span>
</pre><p>
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Duration</span><span class="special">&gt;</span>
  <span class="identifier">count_type</span> <span class="identifier">run_one_until</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span><span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span><span class="special">&gt;&amp;</span> <span class="identifier">abs_time</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> If the <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>
            object has no outstanding work, performs <code class="computeroutput"><span class="identifier">stop</span><span class="special">()</span></code>. Otherwise, blocks while the loop_scheduler
            has outstanding work, or until the expiration of the absolute timeout
            (C++Std [thread.req.timing]) specified by <code class="computeroutput"><span class="identifier">abs_time</span></code>,
            or until the <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>
            is stopped, or until one function object has been executed.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            If an executed function object throws an exception, the exception propagates
            to the caller of <code class="computeroutput"><span class="identifier">run_one</span><span class="special">()</span></code>. The <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>
            state is as if the function object had returned normally.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="number">1</span></code>
            if a function object was executed, otherwise <code class="computeroutput"><span class="number">0</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Notes:</em></span> This function may invoke additional function
            objects through nested calls to the <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>
            executor's <code class="computeroutput"><span class="identifier">dispatch</span></code> member
            function. These do not count towards the return value.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">count_type</span> <span class="identifier">poll</span><span class="special">();</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Equivalent to:
</p><pre class="programlisting"><span class="identifier">count_type</span> <span class="identifier">n</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">poll_one</span><span class="special">())</span>
  <span class="keyword">if</span> <span class="special">(</span><span class="identifier">n</span> <span class="special">!=</span> <span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">count_type</span><span class="special">&gt;::</span><span class="identifier">max</span><span class="special">())</span>
    <span class="special">++</span><span class="identifier">n</span><span class="special">;</span>
</pre><p>
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">n</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">count_type</span> <span class="identifier">poll_one</span><span class="special">();</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> If the <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>
            object has no outstanding work, performs <code class="computeroutput"><span class="identifier">stop</span><span class="special">()</span></code>. Otherwise, if there is a function
            object ready for immediate execution, executes it.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            If an executed function object throws an exception, the exception propagates
            to the caller of <code class="computeroutput"><span class="identifier">poll_one</span><span class="special">()</span></code>. The <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>
            state is as if the function object had returned normally.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="number">1</span></code>
            if a function object was invoked, otherwise <code class="computeroutput"><span class="number">0</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Notes:</em></span> This function may invoke additional function
            objects through nested calls to the <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>
            executor's <code class="computeroutput"><span class="identifier">dispatch</span></code> member
            function. These do not count towards the return value.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">stop</span><span class="special">();</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Stops the <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>.
            Concurrent calls to any run function will end as soon as possible. If
            a call to a run function is currently executing a function object, the
            call will end only after completion of that function object. The call
            to <code class="computeroutput"><span class="identifier">stop</span><span class="special">()</span></code>
            returns without waiting for concurrent calls to run functions to complete.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="identifier">stopped</span><span class="special">()</span> <span class="special">==</span> <span class="keyword">true</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            [<span class="emphasis"><em>Note:</em></span> When <code class="computeroutput"><span class="identifier">stopped</span><span class="special">()</span> <span class="special">==</span> <span class="keyword">true</span></code>, subsequent calls to a run function
            will exit immediately with a return value of <code class="computeroutput"><span class="number">0</span></code>,
            without executing any function objects. A <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>
            remains in the stopped state until a call to <code class="computeroutput"><span class="identifier">restart</span><span class="special">()</span></code>. &#8212;<span class="emphasis"><em>end note</em></span>]
          </p></blockquote></div><pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">stopped</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="keyword">true</span></code>
            if the <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>
            is stopped.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">restart</span><span class="special">();</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="identifier">stopped</span><span class="special">()</span> <span class="special">==</span> <span class="keyword">false</span></code>.
          </p></blockquote></div></div></div><div class="section" title="12.34.&#160;Class loop_scheduler::executor_type"><div class="titlepage"><div><div><h3 class="title"><a name="classes.loop_scheduler__executor_type"></a>12.34.&#160;Class <code class="literal">loop_scheduler::executor_type</code></h3></div></div></div><pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">experimental</span> <span class="special">{</span>
<span class="keyword">inline namespace</span> <span class="identifier">concurrency_v2</span> <span class="special">{</span>

  <span class="keyword">class</span> <span class="identifier">loop_scheduler</span><span class="special">::</span><span class="identifier">executor_type</span>
  <span class="special">{</span>
  <span class="keyword">public</span><span class="special">:</span>
    <span class="comment">// construct / copy / destroy:</span>

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

    <span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">executor_type</span><span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="comment">// executor operations:</span>

    <span class="keyword">bool</span> <span class="identifier">running_in_this_thread</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="identifier">loop_scheduler</span><span class="special">&amp;</span> <span class="identifier">context</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="keyword">void</span> <span class="identifier">on_work_started</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
    <span class="keyword">void</span> <span class="identifier">on_work_finished</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
      <span class="keyword">void</span> <span class="identifier">dispatch</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
      <span class="keyword">void</span> <span class="identifier">post</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
      <span class="keyword">void</span> <span class="identifier">defer</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
  <span class="special">};</span>

  <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">loop_scheduler</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span>
                  <span class="keyword">const</span> <span class="identifier">loop_scheduler</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
  <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="keyword">const</span> <span class="identifier">loop_scheduler</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span>
                  <span class="keyword">const</span> <span class="identifier">loop_scheduler</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>

  <span class="keyword">template</span><span class="special">&lt;&gt;</span> <span class="keyword">struct</span> <span class="identifier">is_executor</span><span class="special">&lt;</span><span class="identifier">loop_scheduler</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&gt;</span> <span class="special">:</span> <span class="identifier">true_type</span> <span class="special">{};</span>

<span class="special">}</span> <span class="comment">// inline namespace concurrency_v2</span>
<span class="special">}</span> <span class="comment">// namespace experimental</span>
<span class="special">}</span> <span class="comment">// namespace std</span>
</pre><p>
        <code class="computeroutput"><span class="identifier">loop_scheduler</span><span class="special">::</span><span class="identifier">executor_type</span></code> is a type satisfying <a class="link" href="#requirements.executor" title="12.3.3.&#160;Executor requirements">Executor requirements</a>. Objects of
        type <code class="computeroutput"><span class="identifier">loop_scheduler</span><span class="special">::</span><span class="identifier">executor_type</span></code> are associated with a <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>, and function objects submitted
        using the <code class="computeroutput"><span class="identifier">dispatch</span></code>, <code class="computeroutput"><span class="identifier">post</span></code>, or <code class="computeroutput"><span class="identifier">defer</span></code>
        member functions will be executed by the <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>
        from within a run function.]
      </p><div class="section" title="12.34.1.&#160;loop_scheduler::executor_type constructors"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__loop_scheduler__executor_type__constructors"></a>12.34.1.&#160;<code class="literal">loop_scheduler::executor_type</code> constructors</h4></div></div></div><pre class="programlisting"><span class="identifier">executor_type</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span> <span class="special">==</span> <span class="identifier">other</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">executor_type</span><span class="special">(</span><span class="identifier">executor_type</span><span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is equal to the prior value of <code class="computeroutput"><span class="identifier">other</span></code>.
          </p></blockquote></div></div><div class="section" title="12.34.2.&#160;loop_scheduler::executor_type assignment"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__loop_scheduler__executor_type__assignment"></a>12.34.2.&#160;<code class="literal">loop_scheduler::executor_type</code> assignment</h4></div></div></div><pre class="programlisting"><span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span> <span class="special">==</span> <span class="identifier">other</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">executor_type</span><span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Postconditions:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is equal to the prior value of <code class="computeroutput"><span class="identifier">other</span></code>.
          </p></blockquote></div><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
          </p></blockquote></div></div><div class="section" title="12.34.3.&#160;loop_scheduler::executor_type operations"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__loop_scheduler__executor_type__operations"></a>12.34.3.&#160;<code class="literal">loop_scheduler::executor_type</code> operations</h4></div></div></div><pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">running_in_this_thread</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="keyword">true</span></code>
            if the current thread of execution is calling a run function of the associated
            <code class="computeroutput"><span class="identifier">loop_scheduler</span></code> object.
            [<span class="emphasis"><em>Note:</em></span> That is, the current thread of execution's
            call chain includes a run function. &#8212;<span class="emphasis"><em>end note</em></span>]
          </p></blockquote></div><pre class="programlisting"><span class="identifier">loop_scheduler</span><span class="special">&amp;</span> <span class="identifier">context</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> A reference to the associated <code class="computeroutput"><span class="identifier">loop_scheduler</span></code> object.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">on_work_started</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Increment the count of outstanding work
            associated with the <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">void</span> <span class="identifier">on_work_finished</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Decrement the count of outstanding work
            associated with the <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
  <span class="keyword">void</span> <span class="identifier">dispatch</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> If <code class="computeroutput"><span class="identifier">running_in_this_thread</span><span class="special">()</span></code> is <code class="computeroutput"><span class="keyword">true</span></code>,
            calls <code class="literal"><span class="emphasis"><em>DECAY_COPY</em></span></code><code class="computeroutput"><span class="special">(</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Func</span><span class="special">&gt;(</span><span class="identifier">f</span><span class="special">))()</span></code> (C++Std [thread.decaycopy]). [<span class="emphasis"><em>Note:</em></span>
            If <code class="computeroutput"><span class="identifier">f</span></code> exits via an exception,
            the exception propagates to the caller of <code class="computeroutput"><span class="identifier">dispatch</span><span class="special">()</span></code>. &#8212;<span class="emphasis"><em>end note</em></span>] Otherwise,
            calls <code class="computeroutput"><span class="identifier">post</span><span class="special">(</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Func</span><span class="special">&gt;(</span><span class="identifier">f</span><span class="special">),</span> <span class="identifier">a</span><span class="special">)</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
  <span class="keyword">void</span> <span class="identifier">post</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Adds <code class="computeroutput"><span class="identifier">f</span></code>
            to the <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Func</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ProtoAllocator</span><span class="special">&gt;</span>
  <span class="keyword">void</span> <span class="identifier">defer</span><span class="special">(</span><span class="identifier">Func</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">ProtoAllocator</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Effects:</em></span> Adds <code class="computeroutput"><span class="identifier">f</span></code>
            to the <code class="computeroutput"><span class="identifier">loop_scheduler</span></code>.
          </p></blockquote></div></div><div class="section" title="12.34.4.&#160;loop_scheduler::executor_type comparisons"><div class="titlepage"><div><div><h4 class="title"><a name="classes.__loop_scheduler__executor_type__comparisons"></a>12.34.4.&#160;<code class="literal">loop_scheduler::executor_type</code> comparisons</h4></div></div></div><pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">loop_scheduler</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span>
                <span class="keyword">const</span> <span class="identifier">loop_scheduler</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="identifier">addressof</span><span class="special">(</span><span class="identifier">a</span><span class="special">.</span><span class="identifier">context</span><span class="special">())</span> <span class="special">==</span> <span class="identifier">addressof</span><span class="special">(</span><span class="identifier">b</span><span class="special">.</span><span class="identifier">context</span><span class="special">())</span></code>.
          </p></blockquote></div><pre class="programlisting"><span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!=(</span><span class="keyword">const</span> <span class="identifier">loop_scheduler</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">,</span>
                <span class="keyword">const</span> <span class="identifier">loop_scheduler</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">&amp;</span> <span class="identifier">b</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
</pre><div class="blockquote"><blockquote class="blockquote"><p>
            <span class="emphasis"><em>Returns:</em></span> <code class="computeroutput"><span class="special">!(</span><span class="identifier">a</span> <span class="special">==</span> <span class="identifier">b</span><span class="special">)</span></code>.
          </p></blockquote></div></div></div></div><div class="section" title="13.&#160;Acknowledgements"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="executors.acknowledgements"></a>13.&#160;Acknowledgements</h2></div></div></div><p>
      The author would like to thank Jamie Allsop, Arash Partow and Dietmar K&#252;hl
      for providing feedback, corrections and suggestions on early iterations of
      both the library implementation and this proposal.
    </p><p>
      The author would also like to thank Marshall Clow, Jens Maurer, Arash Partow,
      Jamie Allsop, Dietmar K&#252;hl, Detlef Vollmann, Jonathan Wakely, Mikael Kilpel&#228;inen,
      Jens Weller, Michael Wong, Eric Fisselier, and Jeffrey Yasskin for participating
      in the Cologne LWG wording review of the Networking Library TS proposal, which
      contributed significantly to the changes in this revision.
    </p></div><div class="footnotes"><br><hr width="100" align="left"><div class="footnote"><p><sup>[<a name="ftn.executors.library_examples.activatable_objects.f0" href="#executors.library_examples.activatable_objects.f0" class="para">1</a>] </sup>
          The concept itself is not new, however the term is taken from <a href="http://accu.org/index.php/journals/1956" target="_top">Holgate,
          Len, <span class="emphasis"><em>Activatable Object</em></span>, ACCU Overload Journal #122,
          August 2014</a>
        </p></div><div class="footnote"><p><sup>[<a name="ftn.executors.library_examples.actors.f0" href="#executors.library_examples.actors.f0" class="para">2</a>] </sup>
          <a href="http://theron-library.com" target="_top">http://theron-library.com</a>
        </p></div></div></div></body></html>
