<h1class="title">Issues With <aclass="reference"href="http://www.boost-consulting.com/writing/n1550.html">N1550</a> and <aclass="reference"href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1530.html">N1530</a></h1>
<li><aclass="reference"href="#non-uniformity-of-the-lvalue-iterator-bit"id="id5"name="id5">Non-Uniformity of the "<ttclass="literal"><spanclass="pre">lvalue_iterator</span></tt> Bit"</a></li>
<li><aclass="reference"href="#redundancy-of-some-explicit-access-category-flags"id="id6"name="id6">Redundancy of Some Explicit Access Category Flags</a></li>
<li><aclass="reference"href="#new-access-traits-templates-wrong-for-some-iterators"id="id7"name="id7">New Access Traits Templates Wrong For Some Iterators</a><ul>
<p>Several issues with <aclass="reference"href="http://www.boost-consulting.com/writing/n1550.html">N1550</a> (New Iterator Concepts) were raised in
the run-up before the fall 2003 C++ Committee meeting, in a thread
beginning with John Maddock's posting <ttclass="literal"><spanclass="pre">c++std-lib-12187</span></tt>. In
looking at those issues, several other problems came up. This
document addresses those issues and discusses some potential
solutions and their impact on <aclass="reference"href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1530.html">N1530</a> (Iterator Facade and Adaptor).</p>
<h2><aclass="toc-backref"href="#id5"name="non-uniformity-of-the-lvalue-iterator-bit">Non-Uniformity of the "<ttclass="literal"><spanclass="pre">lvalue_iterator</span></tt> Bit"</a></h2>
<p>The proposed <ttclass="literal"><spanclass="pre">iterator_tag</span></tt> class template accepts an "access
bits" parameter which includes a bit to indicate the iterator's
<em>lvalueness</em> (whether its dereference operator returns a reference
to its <ttclass="literal"><spanclass="pre">value_type</span></tt>. The relevant part of <aclass="reference"href="http://www.boost-consulting.com/writing/n1550.html">N1550</a> says:</p>
<blockquote>
The purpose of the <ttclass="literal"><spanclass="pre">lvalue_iterator</span></tt> part of the
<ttclass="literal"><spanclass="pre">iterator_access</span></tt> enum is to communicate to <ttclass="literal"><spanclass="pre">iterator_tag</span></tt>
whether the reference type is an lvalue so that the appropriate
old category can be chosen for the base class. The
<ttclass="literal"><spanclass="pre">lvalue_iterator</span></tt> bit is not recorded in the
<ttclass="literal"><spanclass="pre">iterator_tag::access</span></tt> data member.</blockquote>
<p>The <ttclass="literal"><spanclass="pre">lvalue_iterator</span></tt> bit is not recorded because <aclass="reference"href="http://www.boost-consulting.com/writing/n1550.html">N1550</a> aims to
improve orthogonality of the iterator concepts, and a new-style
iterator's lvalueness is detectable by examining its <ttclass="literal"><spanclass="pre">reference</span></tt>
type. This inside/outside difference is awkward and confusing.</p>
<h2><aclass="toc-backref"href="#id6"name="redundancy-of-some-explicit-access-category-flags">Redundancy of Some Explicit Access Category Flags</a></h2>
<p>Shortly after <aclass="reference"href="http://www.boost-consulting.com/writing/n1550.html">N1550</a> was accepted, we discovered that an iterator's
lvalueness can be determined knowing only its <ttclass="literal"><spanclass="pre">value_type</span></tt>. This
predicate can be calculated even for old-style iterators (on whose
<ttclass="literal"><spanclass="pre">reference</span></tt> type the standard places few requirements). A trait
in the Boost iterator library does it by relying on the compiler's
unwillingness to bind an rvalue to a <ttclass="literal"><spanclass="pre">T&</span></tt> function template
parameter. Similarly, it is possible to detect an iterator's
readability knowing only its <ttclass="literal"><spanclass="pre">value_type</span></tt>. Thus, any interface
which asks the <em>user</em> to explicitly describe an iterator's
lvalue-ness or readability seems to introduce needless complexity.</p>
<h2><aclass="toc-backref"href="#id7"name="new-access-traits-templates-wrong-for-some-iterators">New Access Traits Templates Wrong For Some Iterators</a></h2>
<p>Similarly, the part of <ttclass="literal"><spanclass="pre">is_swappable_iterator</span></tt> which applies to
old-style iterators is:</p>
<preclass="literal-block">
else if (cat is convertible to forward_iterator_tag) {
if (iterator_traits<Iterator>::reference is a const reference)
return false;
else
return true;
} else
return false;
</pre>
<p>In this case false positives are possible for non-writable forward
iterators whose <ttclass="literal"><spanclass="pre">reference</span></tt> type is not a reference, or as above,
any forward, bidirectional, or random access iterator whose
<ttclass="literal"><spanclass="pre">reference</span></tt> is not a constant reference but whose <ttclass="literal"><spanclass="pre">value_type</span></tt>
is not assignable (e.g., because it has a private assignment
operator).</p>
<p>False negatives can be "reasoned away": since it is part of a
writable iterator's concept definition that
<ttclass="literal"><spanclass="pre">is_writable<I>::value</span></tt> is <ttclass="literal"><spanclass="pre">true</span></tt>, any iterator for which
it is <ttclass="literal"><spanclass="pre">false</span></tt> is by definition not writable. This seems like a
perverse use of logic, though.</p>
<p>It might be reasonable to conclude that it is a defect that the
standard allows forward iterators with a <ttclass="literal"><spanclass="pre">reference</span></tt> type other
than <ttclass="literal"><spanclass="pre">value_type</span></tt><em>cv</em><ttclass="literal"><spanclass="pre">&</span></tt>, but that still leaves the problem
of old-style iterators whose <ttclass="literal"><spanclass="pre">value_type</span></tt> is not assignable. It
is not possible to correctly compute writability and swappability
for those old-style iterators without intervention
(specializations of <ttclass="literal"><spanclass="pre">is_writable_iterator</span></tt> and
<ttclass="literal"><spanclass="pre">is_swappable_iterator</span></tt>) from a user.</p>
<p><ttclass="literal"><spanclass="pre">is_swappable_iterator<I></span></tt> is supposed to yield true if
<ttclass="literal"><spanclass="pre">iter_swap(x,y)</span></tt> is valid for instances <ttclass="literal"><spanclass="pre">x</span></tt> and <ttclass="literal"><spanclass="pre">y</span></tt> of type
<ttclass="literal"><spanclass="pre">I</span></tt>. The only argument we have heard for
<ttclass="literal"><spanclass="pre">is_swappable_iterator</span></tt> goes something like this:</p>
<blockquote>
<em>"If</em><ttclass="literal"><spanclass="pre">is_swappable_iterator</span></tt><em>yields</em><ttclass="literal"><spanclass="pre">false</span></tt><em>, you
could fall back to using copy construction and assignment on
<ttclass="literal"><spanclass="pre">is_writable_iterator</span></tt> and <ttclass="literal"><spanclass="pre">is_swappable_iterator</span></tt> is that they
can be used to remove algorithms from an overload set using a
SFINAE technique like <aclass="reference"href="http://tinyurl.com/tsr7">enable_if</a>, thus minimizing unintentional
matches due to Koenig Lookup. If it means requiring explicit
indications of writability and swappability from new-style iterator
implementors, however, it seems to be too small a gain to be worth
the cost. That's especially true since we can't get many existing
old-style iterators to meet the same requirements.</p>
<h2><aclass="toc-backref"href="#id19"name="impact-on-n1530-iterator-facade-and-adaptor">Impact on <aclass="reference"href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1530.html">N1530</a> (Iterator Facade and Adaptor)</a></h2>
Generated by <aclass="reference"href="http://docutils.sourceforge.net/">Docutils</a> from <aclass="reference"href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.