<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
  
  <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>Delimited iterators</title>

  
</head>
<body>
<p>N3581<br/>
2013-03-16<br/>
Mike Spertus, Symantec<br/>
<a href="mailto:mike_spertus@symantec.com">mike_spertus@symantec.com</a><br/>
<br/></p>
<h1>Delimited iterators</h1>
<p>It is extremely tempting to use <tt>ostream_iterator</tt> to, say, print
a vector like:
<code>vector&lt;int&gt; v = {1, 4, 6};
cout << "(";
copy(v.begin(), v.end(), ostream_iterator&lt;int&gt;(cout, ", "));
cout << ")"; <span class="comment">// Oops! Prints (1, 4, 6, )</span></code></p>
<p>The problem is that the &ldquo;delimiter&rdquo; in the <tt>ostream_iterator</tt>
constructor call is better described as a suffix than a delimeter.</p>
<p>We offer two alternate proposals</p>
<h2>Option 1</h2>
<p>Add a constructor to <tt>ostream_iterator</tt> that also takes a boolean
argument saying whether you want a suffix. We can now easily print a vector correctly:
<code>vector&lt;int&gt; v = {1, 4, 6};
cout << "(";
copy(v.begin(), v.end(), ostream_iterator&lt;int&gt;(cout, ", ", false));
cout << ")"; <span class="comment">// Prints (1, 4, 6) as desired</span></code></p>
<h2>Option 2</h2>
<p>In case we would rather not modify <tt>ostream_iterator</tt>, we could add
a new <tt>delimited_iterator</tt> class that acts like <tt>ostream_iterator</tt>
except that the delimiter is only placed between output elements:
<code>vector&lt;int&gt; v = {1, 4, 6};
cout << "(";
copy(v.begin(), v.end(), delimited_iterator&lt;int&gt;(cout, ", "));
cout << ")"; <span class="comment">// Prints (1, 4, 6) as desired</span></code></p>
<h2>Implementation</h2>
Straightforward. I give my students a homework assignment to implement <tt>delimited_iterator</tt> every year.
<h2>Wording for option 1</h2>
Modify &sect;24.6.2 [ostream.iterator] as follows:
<blockquote><tt>ostream_iterator</tt> is defined as:<blockquote><pre style="padding:0;margin:0">
namespace std {
  template &lt;class T, class charT = char, class traits = char_traits&lt;charT&gt; &gt;
  class ostream_iterator:
    public iterator&lt;output_iterator_tag, void, void, void, void&gt; {
  public:
 	  typedef charT char_type;
    typedef traits traits_type;
    typedef basic_ostream&lt;charT,traits&gt; ostream_type;
    ostream_iterator(ostream_type&amp; s);
    ostream_iterator(ostream_type&amp; s, const charT* delimiter);
<span class="ins">    ostream_iterator(ostream_type&amp; s, const charT* delimiter, bool is_suffix);</span>
    ostream_iterator(const ostream_iterator&lt;T,charT,traits&gt;&amp; x);
   ~ostream_iterator();
    ostream_iterator&lt;T,charT,traits&gt;&amp; operator=(const T&amp; value);
    ostream_iterator&lt;T,charT,traits&gt;&amp; operator*();
    ostream_iterator&lt;T,charT,traits&gt;&amp; operator++();
    ostream_iterator&lt;T,charT,traits&gt;&amp; operator++(int);
  private:
    basic_ostream&lt;charT,traits&gt;* out_stream; <span class="comment">// exposition only</span>
    const charT* delim; <span class="comment">// exposition only</span>
    <span class="ins">bool suf; <span class="comment">// exposition only</span>
    bool first_element; <span class="comment">// exposition only</span></span>
  };
}</pre></blockquote></blockquote>
Modify &sect;24.6.2.1 [ostream.iterator.cons.des] as follows:
<blockquote><tt>ostream_iterator(ostream_type&amp; s, const charT* delimiter);</tt>
<blockquote><em>Effects:</em> Initializes <em>out_stream</em> 
with <tt>&amp;s</tt><span class="ins">,</span> <span class="del">and </span><em>delim</em> with <tt>delimiter</tt><span class="ins">,
<em>suf</em> with <tt>false</tt>, and <em>first_element</em> with <tt>true</tt>.</span></blockquote>
<span class="ins"><tt>ostream_iterator(ostream_type&amp; s, const charT* delimiter, bool is_suffix);</tt></span>
<blockquote><span class="ins"><em>Effects:</em> Initializes <em>out_stream</em> 
with <tt>&amp;s</tt>, <em>delim</em> with <tt>delimiter</tt>, <em>suf</em> with <tt>is_suffix</tt>,
and <em>first_element</em> with <tt>true</tt>.</span></blockquote>
<tt>ostream_iterator(const ostream_iterator&amp; x);</tt>
<blockquote><em>Effects:</em> Constructs a copy of <tt>x</tt>.</blockquote></blockquote>
Modify &sect;24.6.2.2 [ostream.iterator.ops] as follows:
<blockquote><tt>ostream_iterator&amp; operator=(const T&amp; value);</tt>
<blockquote><em>Effects:</em>
<blockquote><pre style="padding:0;margin:0"><span class="ins">if(<em>delim</em> != 0 &amp;&amp; <em>!suf</em>) {
  if(!<em>first_element</em>)
   <em>out_stream</em> &lt;&lt; <em>delim</em>;
  <em>first_element</em> = false;
}</span>
*<em>out_stream</em> << value;
if(<em>delim</em> != 0<span class="ins"> &amp;&amp; suf</span>)
  *<em>out_stream</em> &lt;&lt; <em>delim</em>;
return (*this);</pre></blockquote></blockquote></blockquote>
<h2>Wording for option 2</h2>
Modify &sect;24.3 [iterator.synopsis] as follows:
<blockquote><pre style="padding:0;margin:0">template &lt;class T, class charT = char, class traits = char_traits&lt;charT&gt; &gt;
class ostream_iterator;
<span class="ins">template &lt;class T, class charT = char, class traits = char_traits&lt;charT&gt; &gt;
class delimited_iterator;</span>
template&lt;class charT, class traits = char_traits&lt;charT&gt; &gt;
class istreambuf_iterator;</pre></blockquote>
Add a section &sect;24.6.x named &ldquo;Class template delimited_iterator&rdquo; [delimited.iterator] between &sect;24.6.2 [ostream.iterator] and 
&sect;24.6.3 [istreambuf.iterator]. This section should be the same as &sect;24.6.2
with all occurrences of <tt>ostream_iterator</tt> replaced with <tt>delimited_iterator</tt>
<em>mutatis mutandis</em>
except as follows:
Make &sect;24.6.x [delimited.iterator] as follows:
<blockquote><span class="ins"><tt>delimited_iterator</tt> is defined as:</span>
<blockquote><pre style="padding:0;margin:0"><span class="ins">
namespace std {
  template &lt;class T, class charT = char, class traits = char_traits&lt;charT&gt; &gt;
  class delimited_iterator:
    public iterator&lt;output_iterator_tag, void, void, void, void&gt; {
  public:
 	  typedef charT char_type;
    typedef traits traits_type;
    typedef basic_ostream&lt;charT,traits&gt; ostream_type;
    ostream_iterator(ostream_type&amp; s);
    delimited_iterator(ostream_type&amp; s, const charT* delimiter);
    delimited_iterator(const ostream_iterator&lt;T,charT,traits&gt;&amp; x);
   ~delimited_iterator();
    delimited_iterator&lt;T,charT,traits&gt;&amp; operator=(const T&amp; value);
    delimited_iterator&lt;T,charT,traits&gt;&amp; operator*();
    delimited_iterator&lt;T,charT,traits&gt;&amp; operator++();
    delimited_iterator&lt;T,charT,traits&gt;&amp; operator++(int);
  private:
    basic_ostream&lt;charT,traits&gt;* out_stream; <span class="comment">// exposition only</span>
    const charT* delim; <span class="comment">// exposition only</span>
    bool first_element; <span class="comment">// exposition only</span>
  };
}</span></pre></blockquote></blockquote>
The corresponding portion of &sect;24.6.x.1 [delimited.iterator.cons.des] should look as follows:
<blockquote><span class="ins"><tt>delimited_iterator(ostream_type&amp; s, const charT* delimiter);</tt></span>
<blockquote><span class="ins"><em>Effects:</em> Initializes <em>out_stream</em> 
with <tt>&amp;s</tt>, <em>delim</em> with <tt>delimiter</tt>,
 and <em>first_element</em> with <tt>true</tt>.</span></blockquote>
<span class="ins"><tt>delimited_iterator(ostream_type&amp; s, const charT* delimiter, bool is_suffix);</tt></span>
<blockquote><span class="ins"><em>Effects:</em> Initializes <em>out_stream</em> 
with <tt>&amp;s</tt>, <em>delim</em> with <tt>delimiter</tt>
and <em>first_element</em> with <tt>true</tt>.</span></blockquote>
<span class="ins"><tt>delimited_iterator(const delimited_iterator&amp; x);</tt></span>
<blockquote><span class="ins"><em>Effects:</em> Constructs a copy of <tt>x</tt>.</span></blockquote></blockquote>
The corresponding portion &sect;24.6.x.2 [delimited.iterator.ops] should look as follows:
<blockquote><span class="ins"><tt>delimited_iterator&amp; operator=(const T&amp; value);</tt></span>
<blockquote><span class="ins"><em>Effects:</em></span>
<blockquote><pre style="padding:0;margin:0"><span class="ins">if(<em>delim</em> != 0) {
  if(!<em>first_element</em>)
   <em>out_stream</em> &lt;&lt; <em>delim</em>;
  <em>first_element</em> = false;
}
*<em>out_stream</em> << value;
return (*this);</span></pre></blockquote></blockquote></blockquote>

</body>
</html>
