<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- saved from url=(0095)http://wiki.edg.com/twiki/pub/Wg21rapperswil2014/LibraryEvolutionWorkingGroup/N4007_updated.htm -->
<html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1252">

  
  <style type="text/css">
.comment { color: #999999; font-style: italic; }
.pre { color: #000099; }
.string { color: #009900; }
.char { color: #009900; }
.float { color: #996600; }
.int { color: #999900; }
.bool { color: #000000; font-weight: bold; }
.type { color: #FF6633; }
.flow { color: #FF0000; }
.keyword { color: #990000; }
.operator { color: #663300; font-weight: bold; }
.operator { color: #663300; font-weight: bold; }
pre.code {
    border: 2px solid #666;
    background-color: #F4F4F4;
    padding-left: 10px;
    padding-top: 0px;
}
code {
    border: 2px solid #d0d0d0;
    background-color: LightYellow;
    padding: 2px;
    padding-left: 10px;
    display:table;
    white-space:pre;
    margin:2px;
    margin-bottom:10px;
}
dt
{
    font-weight: bold;
}
    
.ins {
    background-color:#A0FFA0;
}

.del {
    background-color:#FFA0A0;
    text-decoration:line-through
}    
  </style>
  <title>ostream_joiner</title>

  
<style type="text/css">
table {
  table-layout: fixed ;
}
td {
  width: 20% ;
} 
</style></head>
<body>
<p>P1293R2<br>
Revision of P1293R1<br>
2019-01-21<br>
Mike Spertus, Symantec<br>
<a href="mailto:mike_spertus@symantec.com">mike_spertus@symantec.com</a><br>
Nathan Wilson<br>
<a href="mailto:nwilson20@gmail.com">nwilson20@gmail.com</a><br>
Target: Library Evolution, Library</p><br>
<h1><tt>ostream_joiner</tt></h1>
<h2>Status update</h2>
This paper provides wording for 
	merging into C++20 <tt>ostream_joiner</tt> with the CTAD-related changes below.
	In addition, we have updated the specification as suggested by Casey Carter to meet
	the requirements of C++20 output iterators as described below.<p>
	The main purpose of assigning this revision to LEWG is to clarify LEWG polling
	from San Diego<p>
	The following LEWG straw polls from San Diego provide support for merging <tt>ostream_joiner</tt>
	in C++20
<blockquote>

	We are interested in fixing the constructor/CTAD/make_ostream_joiner.
<table cellspacing="0" cellpadding="0"  rules="all" border="1">
<tr>
<td bgcolor="#ffffff" valign="top"> SF </td>
<td bgcolor="#ffffff" valign="top"> F </td>
<td bgcolor="#ffffff" valign="top"> N </td>
<td bgcolor="#ffffff" valign="top"> A </td>
<td bgcolor="#ffffff" valign="top"> SA </td>
</tr>
<tr>
<td bgcolor="#edf4f9" valign="top" > 5 </td>
<td bgcolor="#edf4f9" valign="top" > 6 </td>
<td bgcolor="#edf4f9" valign="top" > 0 </td>
<td bgcolor="#edf4f9" valign="top" > 0 </td>
<td bgcolor="#edf4f9" valign="top" > 0 </td>
</tr></table>
<p />
We want to prioritize ostream joiner as per the TS + above ctor change for C++20 (No later than Kona)
<table cellspacing="0" cellpadding="0"  rules="all" border="1">
<tr>
<td bgcolor="#ffffff" valign="top"> SF </td>
<td bgcolor="#ffffff" valign="top"> F </td>
<td bgcolor="#ffffff" valign="top"> N </td>
<td bgcolor="#ffffff" valign="top"> A </td>
<td bgcolor="#ffffff" valign="top"> SA </td>
</tr>
<tr>
<td bgcolor="#edf4f9" valign="top"> 3 </td>
<td bgcolor="#edf4f9" valign="top"> 6 </td>
<td bgcolor="#edf4f9" valign="top"> 2 </td>
<td bgcolor="#edf4f9" valign="top"> 1 </td>
<td bgcolor="#edf4f9" valign="top"> 1 </td>
</tr></table>
	</blockquote>
However, note that there was a previous poll
<blockquote>Explore a solution in a post-ranges design (do nothing for C++20). 
	<table cellspacing="0" cellpadding="0"  rules="all" border="1">
<tr>
<td bgcolor="#ffffff" valign="top"> SF </td>
<td bgcolor="#ffffff" valign="top"> F </td>
<td bgcolor="#ffffff" valign="top"> N </td>
<td bgcolor="#ffffff" valign="top"> A </td>
<td bgcolor="#ffffff" valign="top"> SA </td>
</tr>
<tr>
<td bgcolor="#edf4f9" valign="top"> 2 </td>
<td bgcolor="#edf4f9" valign="top"> 8 </td>
<td bgcolor="#edf4f9" valign="top"> 5 </td>
<td bgcolor="#edf4f9" valign="top"> 0 </td>
<td bgcolor="#edf4f9" valign="top"> 1 </td>
</tr></table></blockquote>
Based on the above, we propose to merge as above but continue to explore the
design space post-ranges.
<p/>
<h2>Summary</h2>
This paper updates the <tt>ostream_joiner</tt> proposal to reflect experience
    in Library Fundamentals V2 and changes in the core language since then.
    Specifically, we add a deduction guide to ensure that <tt>ostream_joiner</tt>
    is constructed correctly from a C string literal and remove the now-redundant
    <tt>make_ostream_joiner</tt>.
<h2>Deduction guides</h2>
With the addition of class template argument deduction in C++17, it seems desirable
to get rid of the clumsy <tt>make_ostream_joiner</tt> as we did with class templates
    like <tt>boyer_moore_searcher</tt>. However, as Nathan Myers has pointed out,
    without any deduction guide, the decision to take the delimiter by reference
    means that<code>ostream_joiner j(cout, ", ");</code>
    produces a compile time error as the delimiter type is deduced as <tt>char const[3]</tt>.
    To fix this, add the following to providing the following deduction guide
	<code>template&lt;class DelimT, class CharT, class Traits&gt;
ostream_joiner(basic_ostream&lt;CharT, Traits&gt;&amp;, DelimT) -&gt; ostream_joiner&lt;DelimT, CharT, Traits&gt;;</code>
<h2>C++20 iterator requirements</h2>
C++20 output iterators are required to be default constructible, so the wording
below adds a (useless) default constructor and requires the delimiter type to be
Semiregular at Casey Carter's suggestion.
<h2>Wording</h2>
	Based on the above, we propose applying the following wording to the C++20 working draft.
	Modifications to Library Fundamentals TS v2 are as given in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1293r1.html">P1293</a>.<br/><br/>
 Modify iterator.synopsis as follows
    <blockquote><pre>template&lt;class charT, class traits = char_traits&lt;charT>>
  class ostreambuf_iterator;
  
<ins>template &lt;class DelimT, class charT = char, class traits = char_traits&lt;charT>>
  class ostream_joiner;</ins>
</pre></blockquote>
 Add a subsection before iterator.range as follows<blockquote><b>22.6.5&nbsp;Class template <tt>ostream_joiner</tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator.ostream.joiner</b><br/>
<tt>ostream_joiner</tt> writes (using <tt>operator&lt;&lt;</tt>) successive elements onto the output stream from which it was constructed. The delimiter that it was constructed with is written to the stream between every two <tt>T</tt>s that are written. It is not possible to get a value out of the output iterator. Its only use is as an output iterator in situations like 
<blockquote><pre>while (first != last)
  *result++ = *first++;</pre></blockquote>

<tt>ostream_joiner</tt> is defined as
<blockquote><pre>template &lt;class DelimT, class charT = char, class traits = char_traits&lt;charT>>
  requires Semiregular&lt;DelimT&gt;
class ostream_joiner {
public:
  using char_type = charT;
  using traits_type = traits;
  using ostream_type = basic_ostream&lt;charT, traits>;
  using iterator_category = output_iterator_tag;
  using value_type = void;
  using difference_type = ptrdiff_t;
  using pointer = void;
  using reference = void;

  ostream_joiner() = default;
  ostream_joiner(ostream_type&amp; s, const DelimT&amp; delimiter);
  ostream_joiner(ostream_type&amp; s, DelimT&amp;&amp; delimiter);
  template&lt;typename T>
  ostream_joiner&amp; operator=(const T&amp; value);
  ostream_joiner&amp; operator*() noexcept;
  ostream_joiner&amp; operator++() noexcept;
  ostream_joiner&amp; operator++(int) noexcept;
private:
  ostream_type* out_stream = nullptr; // exposition only
  DelimT delim;             // exposition only
  bool first_element = true;       // exposition only
};
  
template&lt;class DelimT, class CharT, class Traits&gt;
ostream_joiner(basic_ostream&lt;CharT, Traits&gt;&amp;, DelimT) -&gt; ostream_joiner&lt;DelimT, CharT, Traits&gt;;</pre></blockquote>
<b>22.6.5.1&nbsp; <tt>ostream_joiner</tt> constructor&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator.ostream.joiner.cons</b><br/>
<pre>ostream_joiner(ostream_type&amp; s, const DelimT&amp; delimiter);</pre>
	<blockquote><em>Effects: </em>Initializes <tt>out_stream</tt> with <tt>addressof(s)</tt>, <tt>delim</tt> with <tt>delimiter</tt>, and <tt>first_element</tt> with <tt>true</tt>. </blockquote>
<pre>ostream_joiner(ostream_type&amp; s, DelimT&amp;&amp; delimiter);</pre>
	<blockquote><em>Effects: </em>Initializes <tt>out_stream</tt> with <tt>addressof(s)</tt>, <tt>delim</tt> with <tt>std::move(delimiter)</tt>, and <tt>first_element</tt> with <tt>true</tt>. </blockquote>
<b>22.6.5.2&nbsp; <tt>ostream_joiner</tt> operations&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator.ostream.joiner.ops</b><br/>
<pre>template&lt;typename T>
ostream_joiner&amp; operator=(const T&amp; value);</pre>
<blockquote><em>Effects: </em>
<pre>  if (!first_element)
    *out_stream &lt;&lt; delim;
  first_element = false;
  *out_stream &lt;&lt; value;
return *this;</pre></blockquote>		
<pre>ostream_joiner&amp; operator*() noexcept;</pre>
<blockquote><em>Returns:</em> <tt>*this</tt>.</blockquote>

	
<pre>ostream_joiner&amp; operator++() noexcept;
ostream_joiner&amp; operator++(int) noexcept;</pre>
<blockquote><em>Returns:</em> <tt>*this</tt>.</blockquote>
	</blockquote>

    </body></html>
