mirror of
https://github.com/boostorg/iterator.git
synced 2025-05-12 14:01:37 +00:00
166 lines
10 KiB
HTML
Executable File
166 lines
10 KiB
HTML
Executable File
<?xml version="1.0" encoding="utf-8" ?>
|
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<meta name="generator" content="Docutils 0.2.8: http://docutils.sourceforge.net/" />
|
|
<title>Problem with is_writable and is_swappable in N1550</title>
|
|
<link rel="stylesheet" href="default.css" type="text/css" />
|
|
</head>
|
|
<body>
|
|
<div class="document" id="problem-with-is-writable-and-is-swappable-in-n1550">
|
|
<h1 class="title">Problem with <tt class="literal"><span class="pre">is_writable</span></tt> and <tt class="literal"><span class="pre">is_swappable</span></tt> in <a class="reference" href="http://www.boost-consulting.com/writing/n1550.html">N1550</a></h1>
|
|
<table class="field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Author:</th><td class="field-body">David Abrahams and Jeremy Siek</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Contact:</th><td class="field-body"><a class="reference" href="mailto:dave@boost-consulting.com">dave@boost-consulting.com</a>, <a class="reference" href="mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</a></td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Organization:</th><td class="field-body"><a class="reference" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University Bloomington</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">date:</th><td class="field-body">$Date$</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Copyright:</th><td class="field-body">Copyright David Abrahams, Jeremy Siek 2003. Use, modification and
|
|
distribution is subject to the Boost Software License,
|
|
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
|
|
at <a class="reference" href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<div class="contents topic" id="table-of-contents">
|
|
<p class="topic-title"><a name="table-of-contents">Table of Contents</a></p>
|
|
<ul class="simple">
|
|
<li><a class="reference" href="#introduction" id="id1" name="id1">Introduction</a></li>
|
|
<li><a class="reference" href="#proposed-resolution" id="id2" name="id2">Proposed Resolution</a></li>
|
|
<li><a class="reference" href="#rationale" id="id3" name="id3">Rationale</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="section" id="introduction">
|
|
<h1><a class="toc-backref" href="#id1" name="introduction">Introduction</a></h1>
|
|
<p>The <tt class="literal"><span class="pre">is_writable</span></tt> and <tt class="literal"><span class="pre">is_swappable</span></tt> traits classes in <a class="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 <tt class="literal"><span class="pre">iterator_traits<X>::iterator_category</span></tt>
|
|
for the old iterator concepts. For backward compatibility,
|
|
<tt class="literal"><span class="pre">is_writable</span></tt> and <tt class="literal"><span class="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
|
|
<tt class="literal"><span class="pre">iterator_category</span></tt> and also the <tt class="literal"><span class="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 <tt class="literal"><span class="pre">is_writable</span></tt> trait definition which
|
|
applies to old iterators is:</p>
|
|
<pre class="literal-block">
|
|
if (cat is convertible to output_iterator_tag)
|
|
return true;
|
|
else if (cat is convertible to forward_iterator_tag
|
|
and iterator_traits<Iterator>::reference is a
|
|
mutable reference)
|
|
return true;
|
|
else
|
|
return false;
|
|
</pre>
|
|
<p>Suppose the <tt class="literal"><span class="pre">value_type</span></tt> of the iterator <tt class="literal"><span class="pre">It</span></tt> has a private
|
|
assignment operator:</p>
|
|
<pre class="literal-block">
|
|
class B {
|
|
public:
|
|
...
|
|
private:
|
|
B& operator=(const B&);
|
|
};
|
|
</pre>
|
|
<p>and suppose the <tt class="literal"><span class="pre">reference</span></tt> type of the iterator is <tt class="literal"><span class="pre">B&</span></tt>. In
|
|
that case, <tt class="literal"><span class="pre">is_writable<It>::value</span></tt> will be true when in fact
|
|
attempting to write into <tt class="literal"><span class="pre">B</span></tt> will cause an error.</p>
|
|
<p>The same problem applies to <tt class="literal"><span class="pre">is_swappable</span></tt>.</p>
|
|
</div>
|
|
<div class="section" id="proposed-resolution">
|
|
<h1><a class="toc-backref" href="#id2" name="proposed-resolution">Proposed Resolution</a></h1>
|
|
<ol class="arabic">
|
|
<li><p class="first">Remove the <tt class="literal"><span class="pre">is_writable</span></tt> and <tt class="literal"><span class="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><p class="first">Change the <tt class="literal"><span class="pre">is_readable</span></tt> specification to be:
|
|
<tt class="literal"><span class="pre">is_readable<X>::type</span></tt> is <tt class="literal"><span class="pre">true_type</span></tt> if the
|
|
result type of <tt class="literal"><span class="pre">X::operator*</span></tt> is convertible to
|
|
<tt class="literal"><span class="pre">iterator_traits<X>::value_type</span></tt> and is <tt class="literal"><span class="pre">false_type</span></tt>
|
|
otherwise. Also, <tt class="literal"><span class="pre">is_readable</span></tt> is required to satisfy
|
|
the requirements for the UnaryTypeTrait concept
|
|
(defined in the type traits proposal).</p>
|
|
<p>Remove the requirement for support of the <tt class="literal"><span class="pre">is_readable</span></tt> trait from
|
|
the Readable Iterator concept.</p>
|
|
</li>
|
|
<li><p class="first">Remove the <tt class="literal"><span class="pre">iterator_tag</span></tt> class.</p>
|
|
</li>
|
|
<li><p class="first">Change the specification of <tt class="literal"><span class="pre">traversal_category</span></tt> to:</p>
|
|
<pre class="literal-block">
|
|
traversal-category(Iterator) =
|
|
let cat = iterator_traits<Iterator>::iterator_category
|
|
if (cat is convertible to incrementable_iterator_tag)
|
|
return cat; // Iterator is a new iterator
|
|
else if (cat is convertible to random_access_iterator_tag)
|
|
return random_access_traversal_tag;
|
|
else if (cat is convertible to bidirectional_iterator_tag)
|
|
return bidirectional_traversal_tag;
|
|
else if (cat is convertible to forward_iterator_tag)
|
|
return forward_traversal_tag;
|
|
else if (cat is convertible to input_iterator_tag)
|
|
return single_pass_iterator_tag;
|
|
else if (cat is convertible to output_iterator_tag)
|
|
return incrementable_iterator_tag;
|
|
else
|
|
return null_category_tag;
|
|
</pre>
|
|
</li>
|
|
</ol>
|
|
</div>
|
|
<div class="section" id="rationale">
|
|
<h1><a class="toc-backref" href="#id3" name="rationale">Rationale</a></h1>
|
|
<ol class="arabic simple">
|
|
<li>There are two reasons for removing <tt class="literal"><span class="pre">is_writable</span></tt>
|
|
and <tt class="literal"><span class="pre">is_swappable</span></tt>. The first is that we do not know of
|
|
a way to fix the specification so that it gives the correct
|
|
answer for all iterators. Second, there was only a weak
|
|
motivation for having <tt class="literal"><span class="pre">is_writable</span></tt> and <tt class="literal"><span class="pre">is_swappable</span></tt>
|
|
there in the first place. The main motivation was simply
|
|
uniformity: we have tags for the old iterator categories
|
|
so we should have tags for the new iterator categories.
|
|
While having tags and the capability to dispatch based
|
|
on the traversal categories is often used, we see
|
|
less of a need for dispatching based on writability
|
|
and swappability, since typically algorithms
|
|
that need these capabilities have no alternative if
|
|
they are not provided.</li>
|
|
<li>We discovered that the <tt class="literal"><span class="pre">is_readable</span></tt> trait can be implemented
|
|
using only the iterator type itself and its <tt class="literal"><span class="pre">value_type</span></tt>.
|
|
Therefore we remove the requirement for <tt class="literal"><span class="pre">is_readable</span></tt> from the
|
|
Readable Iterator concept, and change the definition of
|
|
<tt class="literal"><span class="pre">is_readable</span></tt> so that it works for any iterator type.</li>
|
|
<li>The purpose of the <tt class="literal"><span class="pre">iterator_tag</span></tt> class was to
|
|
bundle the traversal and access category tags
|
|
into the <tt class="literal"><span class="pre">iterator_category</span></tt> typedef.
|
|
With <tt class="literal"><span class="pre">is_writable</span></tt> and <tt class="literal"><span class="pre">is_swappable</span></tt> gone, and
|
|
<tt class="literal"><span class="pre">is_readable</span></tt> no longer in need of special hints,
|
|
there is no reason for iterators to provide
|
|
information about the access capabilities of an iterator.
|
|
Thus there is no need for the <tt class="literal"><span class="pre">iterator_tag</span></tt>. The
|
|
traversal tag can be directly used for the
|
|
<tt class="literal"><span class="pre">iterator_category</span></tt>. If a new iterator is intended to be backward
|
|
compatible with old iterator concepts, a tag type
|
|
that is convertible to both one of the new traversal tags
|
|
and also to an old iterator tag can be created and use
|
|
for the <tt class="literal"><span class="pre">iterator_category</span></tt>.</li>
|
|
<li>The changes to the specification of <tt class="literal"><span class="pre">traversal_category</span></tt> are a
|
|
direct result of the removal of <tt class="literal"><span class="pre">iterator_tag</span></tt>.</li>
|
|
</ol>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|