<h1class="title">Problem with <ttclass="literal"><spanclass="pre">is_writable</span></tt> and <ttclass="literal"><spanclass="pre">is_swappable</span></tt> in <aclass="reference"href="http://www.boost-consulting.com/writing/n1550.html">N1550</a></h1>
<trclass="field"><thclass="field-name">Organization:</th><tdclass="field-body"><aclass="reference"href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University Bloomington</td>
<p>The <ttclass="literal"><spanclass="pre">is_writable</span></tt> and <ttclass="literal"><spanclass="pre">is_swappable</span></tt> traits classes in <aclass="reference"href="http://www.boost-consulting.com/writing/n1550.html">N1550</a>
provide a mechanism for determining at compile time if an iterator
type is a model of the new Writable Iterator and Swappable Iterator
concepts, analogous to <ttclass="literal"><spanclass="pre">iterator_traits<X>::iterator_category</span></tt>
for the old iterator concepts. For backward compatibility,
<ttclass="literal"><spanclass="pre">is_writable</span></tt> and <ttclass="literal"><spanclass="pre">is_swappable</span></tt> not only work with new
iterators, but they also are intended to work for old
iterators (iterators that meet the requirements for one of the
iterator concepts in the current standard). In the case of old
iterators, the writability and swapability is deduced based on the
<ttclass="literal"><spanclass="pre">iterator_category</span></tt> and also the <ttclass="literal"><spanclass="pre">reference</span></tt> type. The
specification for this deduction gives false positives for forward
iterators that have non-assignable value types.</p>
<p>To review, the part of the <ttclass="literal"><spanclass="pre">is_writable</span></tt> trait definition which
<p>Suppose the <ttclass="literal"><spanclass="pre">value_type</span></tt> of the iterator <ttclass="literal"><spanclass="pre">It</span></tt> has a private
<p>and suppose the <ttclass="literal"><spanclass="pre">reference</span></tt> type of the iterator is <ttclass="literal"><spanclass="pre">B&</span></tt>. In
that case, <ttclass="literal"><spanclass="pre">is_writable<It>::value</span></tt> will be true when in fact
attempting to write into <ttclass="literal"><spanclass="pre">B</span></tt> will cause an error.</p>
<p>The same problem applies to <ttclass="literal"><spanclass="pre">is_swappable</span></tt>.</p>
<li><pclass="first">Remove the <ttclass="literal"><spanclass="pre">is_writable</span></tt> and <ttclass="literal"><spanclass="pre">is_swappable</span></tt> traits, and remove the
requirements in the Writable Iterator and Swappable Iterator concepts
that require their models to support these traits.</p>
</li>
<li><pclass="first">Change the <ttclass="literal"><spanclass="pre">is_readable</span></tt> specification to be:
<ttclass="literal"><spanclass="pre">is_readable<X>::type</span></tt> is <ttclass="literal"><spanclass="pre">true_type</span></tt> if the
result type of <ttclass="literal"><spanclass="pre">X::operator*</span></tt> is convertible to
<ttclass="literal"><spanclass="pre">iterator_traits<X>::value_type</span></tt> and is <ttclass="literal"><spanclass="pre">false_type</span></tt>
<p>The argument for <ttclass="literal"><spanclass="pre">Value</span></tt> must be the <ttclass="literal"><spanclass="pre">value_type</span></tt> of the
iterator, possibly const-qualified, <ttclass="literal"><spanclass="pre">Reference</span></tt> must be the
return type of <ttclass="literal"><spanclass="pre">operator*</span></tt><aclass="footnote-reference"href="#id2"id="id1"name="id1"><sup>*</sup></a>, and <ttclass="literal"><spanclass="pre">Traversal</span></tt> the
traversal tag for the iterator.</p>
</li>
</ol>
<!-- I think the language above is still too informal. There is no
"the iterator", when considering iterator_tag in isolation.
Perhaps that language belongs in a non-normative note
``iterator_tag<Value,Reference,Traversal>`` is required to be
convertible to both ``Traversal`` tag and also to the
``iterator_category`` type specified by the following
pseudo-code::
old-category(Value, Reference, Traversal) =
if (Reference is a reference
and Traversal is convertible to forward_traversal_tag)
{
if (Traversal is convertible to random_access_traversal_tag)
return random_access_iterator_tag;
else if (Traversal is convertible to bidirectional_traversal_tag)
return bidirectional_iterator_tag;
else
return forward_iterator_tag;
}
else if (Traversal is convertible to single_pass_traversal_tag
and Reference is convertible to Value)
{
if (Value is const)
return input_iterator_tag;
else
return input_output_iterator_tag;
} else
return output_iterator_tag; -->
<!-- I reformatted the code for legibility; sorry. -->
<tr><tdclass="label"><aclass="fn-backref"href="#id1"name="id2">[*]</a></td><td>Instead of saying "return type of operator*", we could have
said <ttclass="literal"><spanclass="pre">iterator_traits<X>::reference</span></tt>. However, the standard
specifies nothing about <ttclass="literal"><spanclass="pre">iterator_traits<X>::reference</span></tt> in
many cases, which we believe is a defect. Furthermore, in some
cases it explicitly differs from the return type of
<ttclass="literal"><spanclass="pre">operator*</span></tt>, for example see <ttclass="literal"><spanclass="pre">istreambuf_iterator</span></tt>.</td></tr>
</tbody>
</table>
<olclass="arabic"start="4">
<li><pclass="first">Change the specification of <ttclass="literal"><spanclass="pre">traversal_category</span></tt> to:</p>
Generated by <aclass="reference"href="http://docutils.sourceforge.net/">Docutils</a> from <aclass="reference"href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.