<html><head><meta charset="UTF-8">
<title>Wording for Networking TS changes discussed in Kona</title>
  <style type='text/css'>
  body {font-variant-ligatures: none;}
  p {text-align:justify}
  li {text-align:justify}
  blockquote.note, div.note
  {
          background-color:#E0E0E0;
          padding-left: 15px;
          padding-right: 15px;
          padding-top: 1px;
          padding-bottom: 1px;
  }
  p code {color:navy}
  ins p code {color:#00A000}
  p ins code {color:#00A000}
  p del code {color:#A00000}
  ins {color:#00A000}
  del {color:#A00000}
  table#boilerplate { border:0 }
  table#boilerplate td { padding-left: 2em }
  table.bordered, table.bordered th, table.bordered td {
    border: 1px solid;
    text-align: center;
  }
  ins.block {color:#00A000; text-decoration: none}
  del.block {color:#A00000; text-decoration: none}
  </style>
</head><body>
<table id="boilerplate">
<tr><td>Document number</td><td>P0405R0</td></tr>
<tr><td>Date</td><td>2015-06-28</td></tr>
<tr><td>Project</td><td>Programming Language C++, Library Working Group</td></tr>
<tr><td>Reply-to</td><td>Jonathan Wakely &lt;cxx&#x40;kayari.org&gt;</td></tr>
</table><hr>
<h1>Wording for Networking TS changes discussed in Kona</h1>
<ul>
 <li>
 <ul>
  <li><a href="#Introduction">Introduction</a></li>
  <li><a href="#Removing.default.template.argument.of..code.async_result..code.">Removing default template argument of <code>async_result</code></a>
  <ul>
   <li><a href="#LEWG.Discussion.Notes">LEWG Discussion Notes</a></li>
   <li><a href="#Proposed.Wording">Proposed Wording</a></li>
  </ul>
  </li>
  <li><a href="#Add..code.operator....code..to.buffer.types">Add <code>operator+=</code> to buffer types</a>
  <ul>
   <li><a href="#LEWG.Discussion.Notes">LEWG Discussion Notes</a></li>
   <li><a href="#Proposed.Wording">Proposed Wording</a></li>
  </ul>
  </li>
  <li><a href="#Shallow.constness.of.executors.">Shallow constness of executors.</a>
  <ul>
   <li><a href="#LEWG.Discussion.Notes">LEWG Discussion Notes</a></li>
   <li><a href="#Proposed.Wording">Proposed Wording</a></li>
  </ul>
  </li>
  <li><a href="#Remove.unneeded..code.is_executor..code..specializations">Remove unneeded <code>is_executor</code> specializations</a>
  <ul>
   <li><a href="#Proposed.Wording">Proposed Wording</a></li>
  </ul>
  </li>
  <li><a href="#Define.requirements.for.composed.operations.">Define requirements for composed operations.</a></li>
  <li><a href="#Acknowledgments">Acknowledgments</a></li>
 </ul>
 </li>
</ul>
<a name="Introduction"></a>
<h2>Introduction</h2>

<p>In Kona LEWG agreed a few changes to the Networking TS. Due to the C++17
schedule those changes were not yet reviewed by LWG.</p>

<p>This paper provides wording for those changes, as well as some definitions
accidentally omitted from the original proposal that formed the first TS
working draft.</p>

<p>All changes are relative to N4588. The proposed wording changes are not all
presented at the end, but interleaved throughout the document. The project
editor for the TS is happy with this presentation.</p>

<hr />

<a name="Removing.default.template.argument.of..code.async_result..code."></a>
<h2>Removing default template argument of <code>async_result</code></h2>

<p>The SFINAE checking made possible by the final template parameter of
<code>async_result</code> was deemed to be unnecessary.  LEWG recommended its removal.</p>

<a name="LEWG.Discussion.Notes"></a>
<h3>LEWG Discussion Notes</h3>

<blockquote><p><a href="https://github.com/chriskohlhoff/asio-tr2/issues/224">Issue 224: Consider SFINAE-enabling associators</a></p>

<p>Of the three main customisation points <code>async_result</code>, <code>associated_executor</code>
and <code>associated_allocator</code>, only <code>async_result</code> has a <code>class = void</code> template
parameter. Some LWG members strongly disliked this, and in the interest of
consistency it may be best if either <code>async_result</code> loses it or the other two
gain it.</p></blockquote>

<a name="Proposed.Wording"></a>
<h3>Proposed Wording</h3>

<p>Modify the header synopsis in 13.1 [async.synop]:</p>

<pre><code>      template&lt;class CompletionToken, class Signature<del>, class = void</del>&gt;
        class async_result;
</code></pre>

<p>Modify the class synopsis in 13.3 [async.async.result]:</p>

<pre><code>      template&lt;class CompletionToken, class Signature<del>, class = void</del>&gt;
      class async_result
      {
</code></pre>

<hr />

<a name="Add..code.operator....code..to.buffer.types"></a>
<h2>Add <code>operator+=</code> to buffer types</h2>

<p>Based on implementation experience, the lack of a <code>+=</code> operator is a
bothersome inconvenience when working with buffers.  LEWG agreed such an
addition would be useful.</p>

<a name="LEWG.Discussion.Notes"></a>
<h3>LEWG Discussion Notes</h3>

<blockquote><p><a href="https://github.com/chriskohlhoff/asio-tr2/issues/225">Issue 225: Consider operator+= for const_buffer and mutable_buffer</a></p>

<p>The buffer classes already have <code>operator+</code>.</p>

<p>Marshall implemented <code>operator+=</code> in his own implementation. Jonathan Wakely
and Chris Kohlhoff both (independently) wished it was there when testing out
Jon's implementation.</p>

<p>One LWG member didn't like that +/+= were saturating.</p>

<p><code>string_view</code> uses the name <code>remove_prefix</code> for a similar operation.</p></blockquote>

<a name="Proposed.Wording"></a>
<h3>Proposed Wording</h3>

<p>Add to the class synopsis in 16.4 [buffer.mutable]:</p>

<pre><code>      class mutable_buffer
      {
      public:
        // constructors:
        mutable_buffer() noexcept;
        mutable_buffer(void* p, size_t n) noexcept;
        // members:
        void* data() const noexcept;
        size_t size() const noexcept;
        <ins>mutable_buffer&amp; operator+=(size_t n) noexcept;</ins>
</code></pre>

<p>Add the function definition to the end of 16.4 [buffer.mutable]:</p>

<p><ins></p>

<blockquote><p><ins><code>mutable_buffer&amp; operator+=(size_t n) noexcept;</code></ins></p>

<p><ins>-6- <em>Effects:</em> Sets <code>data_</code> to <code>static_cast&lt;char*&gt;(data_) + min(n, size_)</code>, and then <code>size_</code> to <code>size_ - min(n, size_)</code>.</ins></p>

<p><ins>-7- <em>Returns:</em> <code>*this</code>.</ins></p></blockquote>

<p>Add to the class synopsis in 16.5 [buffer.const]:</p>

<pre><code>      class const_buffer
      {
      public:
        // constructors:
        const_buffer() noexcept;
        const_buffer(const void* p, size_t n) noexcept;
        const_buffer(const mutable_buffer&amp; b) noexcept;
        // members:
        const void* data() const noexcept;
        size_t size() const noexcept;
        <ins>const_buffer&amp; operator+=(size_t n) noexcept;</ins>
</code></pre>

<p>Add the function definition to the end of 16.5 [buffer.const]:</p>

<blockquote><p><ins><code>const_buffer&amp; operator+=(size_t n) noexcept;</code></ins></p>

<p><ins>-7- <em>Effects:</em> Sets <code>data_</code> to <code>static_cast&lt;const char*&gt;(data_) + min(n, size_)</code>, and then <code>size_</code> to <code>size_ - min(n, size_)</code>.</ins></p>

<p><ins>-8- <em>Returns:</em> <code>*this</code>.</ins></p></blockquote>

<hr />

<a name="Shallow.constness.of.executors."></a>
<h2>Shallow constness of executors.</h2>

<p>During implementation a problem was discovered in the TS working paper, where
comparison of const-qualified executor objects was specified in terms of calls
to non-const member functions. The proposed resolution adds <code>const</code> to the
accessors of executors.  The new design is consistent with other handle types
which do not propagate const in accessors, e.g. in the <code>operator*</code> and <code>get()</code>
member functions of iterators and smart pointers.</p>

<a name="LEWG.Discussion.Notes"></a>
<h3>LEWG Discussion Notes</h3>

<blockquote><p><a href="https://github.com/chriskohlhoff/asio-tr2/issues/201">Issue 201: [io_context.exec.comparisons] requires calls to non-const functions</a></p>

<p>Executor objects are shallow and copyable, so it may make sense for the
<code>context()</code> member to be const-qualified. It's a similar relationship to that
between <code>polymorphic_allocator</code> and <code>memory_resource</code>.</p></blockquote>

<a name="Proposed.Wording"></a>
<h3>Proposed Wording</h3>

<p>Modify 13.2.2 [async.reqmts.executor] p6 as shown, and modify Table 4, Executor
requirements, to replace all seven occurrences of <code>cx1</code> with <code>x1</code> and all four
occurrences of <code>cx2</code> with <code>x2</code>:</p>

<blockquote><p>In Table 4, <code>x1</code> and <code>x2</code> denote <ins>(possibly const)</ins> values of type <code>X</code>,
<del><code>cx1</code> and <code>cx2</code> denote (possibly const) values of type <code>X</code>,</del> <code>mx1</code>
denotes an xvalue of type <code>X</code>, <code>f</code> denotes a <code>MoveConstructible</code> (C++Std
[moveconstructible]) function object callable with zero arguments, <code>a</code>
denotes a (possibly const) value of type <code>A</code> meeting the <code>Allocator</code>
requirements (C++Std [allocator.requirements]), and <code>u</code> denotes an
identifier.</p></blockquote>

<div class="note"><p>Drafting note: The following edits simply add <code>const</code> to the accessors of
the three classes <code>system_executor</code>, <code>executor</code>, and <code>strand</code>.</p></div>

<p>Modify the class synopsis in 13.18 [async.system.exec] to add <code>const</code> to
the executor operations member functions:</p>

<pre><code>      // executor operations:

      system_context&amp; context() <ins>const</ins> noexcept;

      void on_work_started() <ins>const</ins> noexcept {}
      void on_work_finished() <ins>const</ins> noexcept {}

      template&lt;class Func, class ProtoAllocator&gt;
        void dispatch(Func&amp;&amp; f, const ProtoAllocator&amp; a) <ins>const</ins>;
      template&lt;class Func, class ProtoAllocator&gt;
        void post(Func&amp;&amp; f, const ProtoAllocator&amp; a) <ins>const</ins>;
      template&lt;class Func, class ProtoAllocator&gt;
        void defer(Func&amp;&amp; f, const ProtoAllocator&amp; a) <ins>const</ins>;
    };
</code></pre>

<p>Modify 13.18.1 [async.system.exec.ops] to add <code>const</code> to the member function
signatures:</p>

<pre><code>    system_context&amp; context() <ins>const</ins> noexcept;

    [...]

    template&lt;class Func, class ProtoAllocator&gt;
      void dispatch(Func&amp;&amp; f, const ProtoAllocator&amp; a) <ins>const</ins>;

    [...]

    template&lt;class Func, class ProtoAllocator&gt;
      void post(Func&amp;&amp; f, const ProtoAllocator&amp; a) <ins>const</ins>;
    template&lt;class Func, class ProtoAllocator&gt;
      void defer(Func&amp;&amp; f, const ProtoAllocator&amp; a) <ins>const</ins>;

    [...]
</code></pre>

<p>Modify the class synopsis in 13.21 [async.executor] to add <code>const</code> to the
executor operations member functions:</p>

<pre><code>      // executor operations:

      execution_context&amp; context() <ins>const</ins> noexcept;

      void on_work_started() <ins>const</ins> noexcept;
      void on_work_finished() <ins>const</ins> noexcept;

      template&lt;class Func, class ProtoAllocator&gt;
        void dispatch(Func&amp;&amp; f, const ProtoAllocator&amp; a) <ins>const</ins>;
      template&lt;class Func, class ProtoAllocator&gt;
        void post(Func&amp;&amp; f, const ProtoAllocator&amp; a) <ins>const</ins>;
      template&lt;class Func, class ProtoAllocator&gt;
        void defer(Func&amp;&amp; f, const ProtoAllocator&amp; a) <ins>const</ins>;

      // executor capacity:
</code></pre>

<p>Modify 13.21.5 [async.executor.ops] to add <code>const</code> to the member function
signatures:</p>

<pre><code>    execution_context&amp; context() <ins>const</ins> noexcept;

    [...]

    void on_work_started() <ins>const</ins> noexcept;

    [...]

    void on_work_finished() <ins>const</ins> noexcept;

    [...]

    template&lt;class Func, class ProtoAllocator&gt;
      void dispatch(Func&amp;&amp; f, const ProtoAllocator&amp; a) <ins>const</ins>;

    [...]

    template&lt;class Func, class ProtoAllocator&gt;
      void post(Func&amp;&amp; f, const ProtoAllocator&amp; a) <ins>const</ins>;

    [...]

    template&lt;class Func, class ProtoAllocator&gt;
      void defer(Func&amp;&amp; f, const ProtoAllocator&amp; a) <ins>const</ins>;

    [...]
</code></pre>

<p>Modify the class synopsis in 13.25 [async.strand] to add <code>const</code> to the
strand operations member functions:</p>

<pre><code>      // strand operations:

      inner_executor_type get_inner_executor() const noexcept;

      bool running_in_this_thread() const noexcept;

      execution_context&amp; context() <ins>const</ins> noexcept;

      void on_work_started() <ins>const</ins> noexcept;
      void on_work_finished() <ins>const</ins> noexcept;

      template&lt;class Func, class ProtoAllocator&gt;
        void dispatch(Func&amp;&amp; f, const ProtoAllocator&amp; a) <ins>const</ins>;
      template&lt;class Func, class ProtoAllocator&gt;
        void post(Func&amp;&amp; f, const ProtoAllocator&amp; a) <ins>const</ins>;
      template&lt;class Func, class ProtoAllocator&gt;
        void defer(Func&amp;&amp; f, const ProtoAllocator&amp; a) <ins>const</ins>;
</code></pre>

<p>Modify 13.25.4 [async.strand.ops] to add <code>const</code> to the member function
signatures:</p>

<pre><code>    execution_context&amp; context() <ins>const</ins> noexcept;

    [...]

    void on_work_started() <ins>const</ins> noexcept;

    [...]

    void on_work_finished() <ins>const</ins> noexcept;

    [...]

    template&lt;class Func, class ProtoAllocator&gt;
      void dispatch(Func&amp;&amp; f, const ProtoAllocator&amp; a) <ins>const</ins>;

    [...]

    template&lt;class Func, class ProtoAllocator&gt;
      void post(Func&amp;&amp; f, const ProtoAllocator&amp; a) <ins>const</ins>;

    [...]

    template&lt;class Func, class ProtoAllocator&gt;
      void defer(Func&amp;&amp; f, const ProtoAllocator&amp; a) <ins>const</ins>;

    [...]
</code></pre>

<hr />

<a name="Remove.unneeded..code.is_executor..code..specializations"></a>
<h2>Remove unneeded <code>is_executor</code> specializations</h2>

<p>This is a quasi-editorial change to remove some redundant specializations.
It would be conforming for implementations to continue to provide the
specializations as an optimization, but their existence has no normative
effect.</p>

<a name="Proposed.Wording"></a>
<h3>Proposed Wording</h3>

<p>Remove the template specialization from the synopsis in 13.21 [async.executor]:</p>

<pre><code>         template&lt;class Executor&gt; const Executor* target() const noexcept;
       };

       <del>template&lt;&gt; struct is_executor&lt;executor&gt; : true_type {};</del>

       // executor comparisons:

       bool operator==(const executor&amp; a, const executor&amp; b) noexcept;
</code></pre>

<p>Remove the template specialization from the synopsis in 14.3 [io_context.exec]:</p>

<pre><code>       bool operator!=(const io_context::executor_type&amp; a,
                       const io_context::executor_type&amp; b) noexcept;

       <del>template&lt;&gt; struct is_executor&lt;io_context::executor_type&gt; : true_type {};</del>

     } // inline namespace v1
     } // namespace net
     } // namespace experimental
</code></pre>

<hr />

<a name="Define.requirements.for.composed.operations."></a>
<h2>Define requirements for composed operations.</h2>

<p>Mr. Kohlhoff writes:</p>

<blockquote><p>This important piece of specification was accidentally omitted when the original TR2 proposal was updated for the proposed technical specification. The wording in this pull request is intended to convey the intent and will certainly require wordsmithing.</p></blockquote>

<p>Add a new sub-clause after 13.2.7.13 [async.reqmts.async.exceptions]</p>

<blockquote><p><strong>13.2.7.14 Composed asynchronous operations [async.reqmts.async.composed]</strong></p>

<p>-1- In this Technical Specification, a <em>composed asynchronous operation</em> is
an asynchronous operation that is implemented in terms of zero or more
intermediate calls to other asynchronous operations. The intermediate
asynchronous operations are performed sequentially. <em>[Note:</em> That is, the
completion handler of an intermediate operation initiates the next operation
in the sequence. <em>--end note]</em></p>

<p>An intermediate operation's completion handler shall have an associated
executor that is either:</p>

<ul>
<li><p>the type <code>Executor2</code> and object <code>ex2</code> obtained from the completion handler
type <code>CompletionHandler</code> and object <code>completion_handler</code>; or</p></li>
<li><p>an object of an unspecified type satisfying the Executor requirements
(13.2.2), that delegates executor operations to the type <code>Executor2</code> and
object <code>ex2</code>.</p></li>
</ul>


<p>An intermediate operation's completion handler shall have an associated
allocator that is either:</p>

<ul>
<li><p>the type <code>Alloc2</code> and object <code>alloc2</code> obtained from the completion handler
type <code>CompletionHandler</code> and object <code>completion_handler</code>; or</p></li>
<li><p>an object of an unspecified type satisfying the ProtoAllocator requirements
(13.2.1 [async.reqmts.proto.allocator]), that delegates allocator operations
to the type <code>Alloc2</code> and object <code>alloc2</code>.</p></li>
</ul>
</blockquote>

<p>Adjust 17.6 [buffer.async.read] p1 to use the new term, and add
a reference to 13.2.7.14 [async.reqmts.async.composed]:</p>

<blockquote><p>-1- A <ins>composed asynchronous</ins> read operation (<ins>13.2.7.14,</ins> 16.2.4).</p></blockquote>

<p>Adjust 17.8 [buffer.async.write] p1 to use the new term, and add
a reference to 13.2.7.14 [async.reqmts.async.composed]:</p>

<blockquote><p>-1- A <ins>composed asynchronous</ins> write operation (<ins>13.2.7.14,</ins> 16.2.4).</p></blockquote>

<p>Add a new paragraph to 17.10 [buffer.async.read.until] using the new term,
with a reference to 13.2.7.14 [async.reqmts.async.composed]):</p>

<blockquote><p><ins>-?- A composed asynchronous operation (13.2.7.14).</ins></p>

<p>-1- <em>Completion signature:</em> <code>void(error_code ec, size_t n)</code>.</p></blockquote>

<p>Add new paragraphs to 20.2 [socket.algo.async.connect] using the new term,
with references to 13.2.7.14 [async.reqmts.async.composed]):</p>

<blockquote><p><ins>-?- A composed asynchronous operation (13.2.7.14).</ins></p>

<p>-1- <em>Completion signature:</em> <code>void(error_code ec, typename Protocol::endpoint ep)</code>.</p>

<p>[...]</p>

<p><ins>-?- A composed asynchronous operation (13.2.7.14).</ins></p>

<p>-7- <em>Completion signature:</em> <code>void(error_code ec, InputIterator i)</code>.</p></blockquote>

<hr />

<a name="Acknowledgments"></a>
<h2>Acknowledgments</h2>

<p>The wording changes in this proposal were all provided by Chris Kohlhoff via
Git pull requests, all I have done is present them in this format for
review. Many thanks to Chris for providing the changes.</p>
</body></html>
