mirror of
https://github.com/boostorg/iterator.git
synced 2025-05-11 05:23:52 +00:00
5269 lines
244 KiB
HTML
Executable File
5269 lines
244 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.3.6: http://docutils.sourceforge.net/" />
|
|
<title>Iterator concept and adapter issues</title>
|
|
<meta name="date" content="2004-01-27" />
|
|
<link rel="stylesheet" href="default.css" type="text/css" />
|
|
</head>
|
|
<body>
|
|
<h1 class="title">Iterator concept and adapter issues</h1>
|
|
<table class="docinfo" frame="void" rules="none">
|
|
<col class="docinfo-name" />
|
|
<col class="docinfo-content" />
|
|
<tbody valign="top">
|
|
<tr><th class="docinfo-name">Date:</th>
|
|
<td>2004-01-27</td></tr>
|
|
</tbody>
|
|
</table>
|
|
<div class="document" id="iterator-concept-and-adapter-issues">
|
|
<div class="contents topic" id="index">
|
|
<p class="topic-title first"><a name="index">Index</a></p>
|
|
<ul class="simple">
|
|
<li><a class="reference" href="#issues-from-matt-s-tr-issues-list" id="id1" name="id1">Issues from Matt's TR issues list</a><ul>
|
|
<li><a class="reference" href="#iterator-access-overspecified" id="id2" name="id2">9.1 iterator_access overspecified?</a></li>
|
|
<li><a class="reference" href="#operators-of-iterator-facade-overspecified" id="id3" name="id3">9.2 operators of iterator_facade overspecified</a></li>
|
|
<li><a class="reference" href="#enable-if-interoperable-needs-standardese" id="id4" name="id4">9.3 enable_if_interoperable needs standardese</a></li>
|
|
<li><a class="reference" href="#enable-if-convertible-unspecified-conflicts-with-requires" id="id5" name="id5">9.4 enable_if_convertible unspecified, conflicts with requires</a></li>
|
|
<li><a class="reference" href="#iterator-adaptor-has-an-extraneous-bool-at-the-start-of-the-template-definition" id="id6" name="id6">9.5 iterator_adaptor has an extraneous 'bool' at the start of the template definition</a></li>
|
|
<li><a class="reference" href="#name-of-private-member-shouldn-t-be-normative" id="id7" name="id7">9.6 Name of private member shouldn't be normative</a></li>
|
|
<li><a class="reference" href="#iterator-adaptor-operations-specifications-are-a-bit-inconsistent" id="id8" name="id8">9.7 iterator_adaptor operations specifications are a bit inconsistent</a></li>
|
|
<li><a class="reference" href="#specialized-adaptors-text-should-be-normative" id="id9" name="id9">9.8 Specialized adaptors text should be normative</a></li>
|
|
<li><a class="reference" href="#reverse-iterator-text-is-too-informal" id="id10" name="id10">9.9 Reverse_iterator text is too informal</a></li>
|
|
<li><a class="reference" href="#prior-is-undefined" id="id11" name="id11">9.10 'prior' is undefined</a></li>
|
|
<li><a class="reference" href="#in-other-words-is-bad-wording" id="id12" name="id12">9.11 "In other words" is bad wording</a></li>
|
|
<li><a class="reference" href="#transform-iterator-shouldn-t-mandate-private-member" id="id13" name="id13">9.12 Transform_iterator shouldn't mandate private member</a></li>
|
|
<li><a class="reference" href="#unclear-description-of-counting-iterator" id="id14" name="id14">9.13 Unclear description of counting iterator</a></li>
|
|
<li><a class="reference" href="#counting-iterator-s-difference-type" id="id15" name="id15">9.14 Counting_iterator's difference type</a></li>
|
|
<li><a class="reference" href="#how-to-detect-lvalueness" id="id16" name="id16">9.15 How to detect lvalueness?</a></li>
|
|
<li><a class="reference" href="#is-writable-iterator-returns-false-positives" id="id17" name="id17">9.16 is_writable_iterator returns false positives</a></li>
|
|
<li><a class="reference" href="#is-swappable-iterator-returns-false-positives" id="id18" name="id18">9.17 is_swappable_iterator returns false positives</a></li>
|
|
<li><a class="reference" href="#are-is-readable-is-writable-and-is-swappable-useful" id="id19" name="id19">9.18 Are is_readable, is_writable, and is_swappable useful?</a></li>
|
|
<li><a class="reference" href="#non-uniformity-of-the-lvalue-iterator-bit" id="id20" name="id20">9.19 Non-Uniformity of the "lvalue_iterator Bit"</a></li>
|
|
<li><a class="reference" href="#traversal-concepts-and-tags" id="id21" name="id21">9.20 Traversal Concepts and Tags</a></li>
|
|
<li><a class="reference" href="#iterator-facade-derived-template-argument-underspecified" id="id22" name="id22">9.21 iterator_facade Derived template argument underspecified</a></li>
|
|
<li><a class="reference" href="#return-type-of-iterator-difference-for-iterator-facade" id="id23" name="id23">9.22 return type of Iterator difference for iterator facade</a></li>
|
|
<li><a class="reference" href="#iterator-facade-minor-wording-issue" id="id24" name="id24">9.23 Iterator_facade: minor wording Issue</a></li>
|
|
<li><a class="reference" href="#use-of-undefined-name-in-iterator-facade-table" id="id25" name="id25">9.24 Use of undefined name in iterator_facade table</a></li>
|
|
<li><a class="reference" href="#iterator-facade-wrong-return-type" id="id26" name="id26">9.25 Iterator_facade: wrong return type</a></li>
|
|
<li><a class="reference" href="#iterator-facade-unclear-returns-clause-for-operator" id="id27" name="id27">9.26 Iterator_facade: unclear returns clause for operator[]</a></li>
|
|
<li><a class="reference" href="#iterator-facade-redundant-clause" id="id28" name="id28">9.27 Iterator_facade: redundant clause</a></li>
|
|
<li><a class="reference" href="#indirect-iterator-incorrect-specification-of-default-constructor" id="id29" name="id29">9.28 indirect_iterator: incorrect specification of default constructor</a></li>
|
|
<li><a class="reference" href="#indirect-iterator-unclear-specification-of-template-constructor" id="id30" name="id30">9.29 indirect_iterator: unclear specification of template constructor</a></li>
|
|
<li><a class="reference" href="#transform-iterator-argument-irregularity" id="id31" name="id31">9.30 transform_iterator argument irregularity</a></li>
|
|
<li><a class="reference" href="#function-output-iterator-overconstrained" id="id32" name="id32">9.31 function_output_iterator overconstrained</a></li>
|
|
<li><a class="reference" href="#should-output-proxy-really-be-a-named-type" id="id33" name="id33">9.32 Should output_proxy really be a named type?</a></li>
|
|
<li><a class="reference" href="#istreambuf-iterator-isn-t-a-readable-iterator" id="id34" name="id34">9.33 istreambuf_iterator isn't a Readable Iterator</a></li>
|
|
<li><a class="reference" href="#iterator-facade-free-functions-unspecified" id="id35" name="id35">9.34 iterator_facade free functions unspecified</a></li>
|
|
<li><a class="reference" href="#iterator-facade-too-many-equals" id="id36" name="id36">9.35 iterator_facade: too many equals?</a></li>
|
|
<li><a class="reference" href="#iterator-facade-function-requirements" id="id37" name="id37">9.36 iterator_facade function requirements</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a class="reference" href="#more-issues-not-from-matt-s-list" id="id38" name="id38">More Issues (not from Matt's list)</a><ul>
|
|
<li><a class="reference" href="#x-inheritance-in-iterator-adaptor-and-other-adaptors-is-an-overspecification" id="id39" name="id39">9.37x Inheritance in iterator_adaptor and other adaptors is an overspecification</a></li>
|
|
<li><a class="reference" href="#x-problem-with-specification-of-a-m-in-readable-iterator" id="id40" name="id40">9.38x Problem with specification of a->m in Readable Iterator</a></li>
|
|
<li><a class="reference" href="#x-counting-iterator-traversal-argument-unspecified" id="id41" name="id41">9.39x counting_iterator Traversal argument unspecified</a></li>
|
|
<li><a class="reference" href="#x-indirect-iterator-requirements-muddled" id="id42" name="id42">9.40x indirect_iterator requirements muddled</a></li>
|
|
<li><a class="reference" href="#x-problem-with-transform-iterator-requirements" id="id43" name="id43">9.41x Problem with transform_iterator requirements</a></li>
|
|
<li><a class="reference" href="#x-filter-iterator-details-unspecified" id="id44" name="id44">9.42x filter_iterator details unspecified</a></li>
|
|
<li><a class="reference" href="#x-transform-iterator-interoperability-too-restrictive" id="id45" name="id45">9.43x transform_iterator interoperability too restrictive</a></li>
|
|
<li><a class="reference" href="#y-indirect-iterator-and-smart-pointers" id="id46" name="id46">9.44y <tt class="literal"><span class="pre">indirect_iterator</span></tt> and smart pointers</a></li>
|
|
<li><a class="reference" href="#y-n1530-typos-and-editorial-changes-in-proposal-text-not-standardese" id="id47" name="id47">9.45y N1530: Typos and editorial changes in proposal text (not standardese)</a></li>
|
|
<li><a class="reference" href="#y-n1530-base-return-by-value-is-costly" id="id48" name="id48">9.46y N1530: <tt class="literal"><span class="pre">base()</span></tt> return-by-value is costly</a></li>
|
|
<li><a class="reference" href="#x-forgot-default-constructible-in-forward-traversal-iterator" id="id49" name="id49">9.47x Forgot default constructible in Forward Traversal Iterator</a></li>
|
|
<li><a class="reference" href="#x-editorial-changes-non-normative-text" id="id50" name="id50">9.48x Editorial changes (non-normative text)</a></li>
|
|
<li><a class="reference" href="#x-clarification-of-iterator-facade-requirements-and-type-members" id="id51" name="id51">9.49x Clarification of iterator_facade requirements and type members</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="section" id="issues-from-matt-s-tr-issues-list">
|
|
<h1><a class="toc-backref" href="#id1" name="issues-from-matt-s-tr-issues-list">Issues from Matt's TR issues list</a></h1>
|
|
<div class="section" id="iterator-access-overspecified">
|
|
<h2><a class="toc-backref" href="#id2" name="iterator-access-overspecified">9.1 iterator_access overspecified?</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>The proposal includes:</p>
|
|
<pre class="literal-block">
|
|
enum iterator_access {
|
|
readable_iterator = 1, writable_iterator = 2,
|
|
swappable_iterator = 4, lvalue_iterator = 8
|
|
};
|
|
</pre>
|
|
<p>In general, the standard specifies thing like this as a bitmask
|
|
type with a list of defined names, and specifies neither the exact
|
|
type nor the specific values. Is there a reason for iterator_access
|
|
to be more specific?</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body">The <tt class="literal"><span class="pre">iterator_access</span></tt> enum will be removed,
|
|
so this is no longer an issue. See the resolution to 9.15.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="operators-of-iterator-facade-overspecified">
|
|
<h2><a class="toc-backref" href="#id3" name="operators-of-iterator-facade-overspecified">9.2 operators of iterator_facade overspecified</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>In general, we've provided operational semantics for things like
|
|
operator++. That is, we've said that ++iter must work, without
|
|
requiring either a member function or a non-member function.
|
|
iterator_facade specifies most operators as member
|
|
functions. There's no inherent reason for these to be members, so
|
|
we should remove this requirement. Similarly, some operations are
|
|
specified as non-member functions but could be implemented as
|
|
members. Again, the standard doesn't make either of these choices,
|
|
and TR1 shouldn't, either. So: <tt class="literal"><span class="pre">operator*()</span></tt>, <tt class="literal"><span class="pre">operator++()</span></tt>,
|
|
<tt class="literal"><span class="pre">operator++(int)</span></tt>, <tt class="literal"><span class="pre">operator--()</span></tt>, <tt class="literal"><span class="pre">operator--(int)</span></tt>,
|
|
<tt class="literal"><span class="pre">operator+=</span></tt>, <tt class="literal"><span class="pre">operator-=</span></tt>, <tt class="literal"><span class="pre">operator-(difference_type)</span></tt>,
|
|
<tt class="literal"><span class="pre">operator-(iterator_facade</span> <span class="pre">instance)</span></tt>, and <tt class="literal"><span class="pre">operator+</span></tt> should
|
|
be specified with operational semantics and not explicitly required
|
|
to be members or non-members.</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body">Not a defect.</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Rationale:</th><td class="field-body">The standard uses valid expressions such as <tt class="literal"><span class="pre">++iter</span></tt>
|
|
in requirements tables, such as for input iterator. However, for
|
|
classes, such as <tt class="literal"><span class="pre">reverse_iterator</span></tt>, the standard uses function
|
|
prototypes, as we have done here for
|
|
<tt class="literal"><span class="pre">iterator_facade</span></tt>. Further, the prototype specification does
|
|
not prevent the implementor from using members or non-members,
|
|
since nothing the user can do in a conforming program can detect
|
|
how the function is implemented.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="enable-if-interoperable-needs-standardese">
|
|
<h2><a class="toc-backref" href="#id4" name="enable-if-interoperable-needs-standardese">9.3 enable_if_interoperable needs standardese</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>The only discussion of what this means is in a note, so is
|
|
non-normative. Further, the note seems to be incorrect. It says
|
|
that enable_if_interoperable only works for types that "are
|
|
interoperable, by which we mean they are convertible to each
|
|
other." This requirement is too strong: it should be that one of
|
|
the types is convertible to the other. N1541 48</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">Add normative text. Relax requirements in the
|
|
proposed way.</p>
|
|
<p>Change:</p>
|
|
<blockquote>
|
|
[<em>Note:</em> The <tt class="literal"><span class="pre">enable_if_interoperable</span></tt> template used above is
|
|
for exposition purposes. The member operators should be only be
|
|
in an overload set provided the derived types <tt class="literal"><span class="pre">Dr1</span></tt> and
|
|
<tt class="literal"><span class="pre">Dr2</span></tt> are interoperable, by which we mean they are
|
|
convertible to each other. The <tt class="literal"><span class="pre">enable_if_interoperable</span></tt>
|
|
approach uses SFINAE to take the operators out of the overload
|
|
set when the types are not interoperable.]</blockquote>
|
|
<p>To:</p>
|
|
<blockquote class="last">
|
|
<p>The <tt class="literal"><span class="pre">enable_if_interoperable</span></tt> template used above is for
|
|
exposition purposes. The member operators should only be in an
|
|
overload set provided the derived types <tt class="literal"><span class="pre">Dr1</span></tt> and <tt class="literal"><span class="pre">Dr2</span></tt> are
|
|
interoperable, meaning that at least one of the types is
|
|
convertible to the other. The <tt class="literal"><span class="pre">enable_if_interoperable</span></tt>
|
|
approach uses SFINAE to take the operators out of the overload
|
|
set when the types are not interoperable. The operators should
|
|
behave <em>as-if</em> <tt class="literal"><span class="pre">enable_if_interoperable</span></tt> were defined to be:</p>
|
|
<pre class="literal-block">
|
|
template <bool, typename> enable_if_interoperable_impl
|
|
{};
|
|
|
|
template <typename T> enable_if_interoperable_impl<true,T>
|
|
{ typedef T type; };
|
|
|
|
template<typename Dr1, typename Dr2, typename T>
|
|
struct enable_if_interoperable
|
|
: enable_if_interoperable_impl<
|
|
is_convertible<Dr1,Dr2>::value || is_convertible<Dr2,Dr1>::value
|
|
, T
|
|
>
|
|
{};
|
|
</pre>
|
|
</blockquote>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="enable-if-convertible-unspecified-conflicts-with-requires">
|
|
<h2><a class="toc-backref" href="#id5" name="enable-if-convertible-unspecified-conflicts-with-requires">9.4 enable_if_convertible unspecified, conflicts with requires</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>In every place where enable_if_convertible is used it's used like
|
|
this (simplified):</p>
|
|
<pre class="literal-block">
|
|
template<class T>
|
|
struct C
|
|
{
|
|
template<class T1>
|
|
C(T1, enable_if_convertible<T1, T>::type* = 0);
|
|
};
|
|
</pre>
|
|
<p>The idea being that this constructor won't compile if T1 isn't
|
|
convertible to T. As a result, the constructor won't be considered
|
|
as a possible overload when constructing from an object x where the
|
|
type of x isn't convertible to T. In addition, however, each of
|
|
these constructors has a requires clause that requires
|
|
convertibility, so the behavior of a program that attempts such a
|
|
construction is undefined. Seems like the enable_if_convertible
|
|
part is irrelevant, and should be removed. There are two
|
|
problems. First, enable_if_convertible is never specified, so we
|
|
don't know what this is supposed to do. Second: we could reasonably
|
|
say that this overload should be disabled in certain cases or we
|
|
could reasonably say that behavior is undefined, but we can't say
|
|
both.</p>
|
|
<p>Thomas Witt writes that the goal of putting in
|
|
enable_if_convertible here is to make sure that a specific overload
|
|
doesn't interfere with the generic case except when that overload
|
|
makes sense. He agrees that what we currently have is deficient.
|
|
Dave Abrahams writes that there is no conflict with the requires
|
|
cause because the requires clause only takes effect when the
|
|
function is actually called. The presence of the constructor
|
|
signature can/will be detected by is_convertible without violating
|
|
the requires clause, and thus it makes a difference to disable
|
|
those constructor instantiations that would be disabled by
|
|
enable_if_convertible even if calling them invokes undefined
|
|
behavior. There was more discussion on the reflector:
|
|
c++std-lib-12312, c++std-lib-12325, c++std-lib- 12330,
|
|
c++std-lib-12334, c++std-lib-12335, c++std-lib-12336,
|
|
c++std-lib-12338, c++std-lib- 12362.</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">Change:</p>
|
|
<blockquote>
|
|
[<em>Note:</em> The <tt class="literal"><span class="pre">enable_if_convertible<X,Y>::type</span></tt> expression
|
|
used in this section is for exposition purposes. The converting
|
|
constructors for specialized adaptors should be only be in an
|
|
overload set provided that an object of type <tt class="literal"><span class="pre">X</span></tt> is
|
|
implicitly convertible to an object of type <tt class="literal"><span class="pre">Y</span></tt>. The
|
|
<tt class="literal"><span class="pre">enable_if_convertible</span></tt> approach uses SFINAE to take the
|
|
constructor out of the overload set when the types are not
|
|
implicitly convertible.]</blockquote>
|
|
<p>To:</p>
|
|
<blockquote class="last">
|
|
<p>The <tt class="literal"><span class="pre">enable_if_convertible<X,Y>::type</span></tt> expression used in
|
|
this section is for exposition purposes. The converting
|
|
constructors for specialized adaptors should be only be in an
|
|
overload set provided that an object of type <tt class="literal"><span class="pre">X</span></tt> is
|
|
implicitly convertible to an object of type <tt class="literal"><span class="pre">Y</span></tt>. The
|
|
signatures involving <tt class="literal"><span class="pre">enable_if_convertible</span></tt> should behave
|
|
<em>as-if</em> <tt class="literal"><span class="pre">enable_if_convertible</span></tt> were defined to be:</p>
|
|
<pre class="literal-block">
|
|
template <bool> enable_if_convertible_impl
|
|
{};
|
|
|
|
template <> enable_if_convertible_impl<true>
|
|
{ struct type; };
|
|
|
|
template<typename From, typename To>
|
|
struct enable_if_convertible
|
|
: enable_if_convertible_impl<is_convertible<From,To>::value>
|
|
{};
|
|
</pre>
|
|
<p>If an expression other than the default argument is used to
|
|
supply the value of a function parameter whose type is written
|
|
in terms of <tt class="literal"><span class="pre">enable_if_convertible</span></tt>, the program is
|
|
ill-formed, no diagnostic required.</p>
|
|
<p>[<em>Note:</em> The <tt class="literal"><span class="pre">enable_if_convertible</span></tt> approach uses SFINAE to
|
|
take the constructor out of the overload set when the types are
|
|
not implicitly convertible. ]</p>
|
|
</blockquote>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="iterator-adaptor-has-an-extraneous-bool-at-the-start-of-the-template-definition">
|
|
<h2><a class="toc-backref" href="#id6" name="iterator-adaptor-has-an-extraneous-bool-at-the-start-of-the-template-definition">9.5 iterator_adaptor has an extraneous 'bool' at the start of the template definition</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>The title says it all; this is probably just a typo.</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body">Remove the 'bool'.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="name-of-private-member-shouldn-t-be-normative">
|
|
<h2><a class="toc-backref" href="#id7" name="name-of-private-member-shouldn-t-be-normative">9.6 Name of private member shouldn't be normative</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>iterator_adaptor has a private member named m_iterator. Presumably
|
|
this is for exposition only, since it's an implementation
|
|
detail. It needs to be marked as such.</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><dl class="first">
|
|
<dt>Mark the member <tt class="literal"><span class="pre">m_iterator</span></tt> as exposition</dt>
|
|
<dd>only. Note/DWA: I think this is NAD because the user can't
|
|
detect it, though I'm happy to mark it exposition only.</dd>
|
|
</dl>
|
|
<p>In [lib.iterator.adaptor]</p>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
Base m_iterator;
|
|
</pre>
|
|
<p>to:</p>
|
|
<pre class="last literal-block">
|
|
Base m_iterator; // exposition only
|
|
</pre>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="iterator-adaptor-operations-specifications-are-a-bit-inconsistent">
|
|
<h2><a class="toc-backref" href="#id8" name="iterator-adaptor-operations-specifications-are-a-bit-inconsistent">9.7 iterator_adaptor operations specifications are a bit inconsistent</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>iterator_adpator() has a Requires clause, that Base must be default
|
|
constructible. iterator_adaptor(Base) has no Requires clause,
|
|
although the Returns clause says that the Base member is copy
|
|
construced from the argument (this may actually be an oversight in
|
|
N1550, which doesn't require iterators to be copy constructible or
|
|
assignable).</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">Add a requirements section for the template
|
|
parameters of iterator_adaptor, and state that Base must be Copy
|
|
Constructible and Assignable.</p>
|
|
<p class="last">N1550 does in fact include requirements for copy constructible
|
|
and assignable in the requirements tables. To clarify, we've also
|
|
added the requirements to the text.</p>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="specialized-adaptors-text-should-be-normative">
|
|
<h2><a class="toc-backref" href="#id9" name="specialized-adaptors-text-should-be-normative">9.8 Specialized adaptors text should be normative</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>similar to 9.3, "Specialized Adaptors" has a note describing
|
|
enable_if_convertible. This should be normative text.</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body">Changed it to normative
|
|
text. See the resolution of 9.4</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="reverse-iterator-text-is-too-informal">
|
|
<h2><a class="toc-backref" href="#id10" name="reverse-iterator-text-is-too-informal">9.9 Reverse_iterator text is too informal</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>reverse iterator "flips the direction of the base iterator's
|
|
motion". This needs to be more formal, as in the current
|
|
standard. Something like: "iterates through the controlled sequence
|
|
in the opposite direction"</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">Change:</p>
|
|
<blockquote>
|
|
The reverse iterator adaptor flips the direction of a base
|
|
iterator's motion. Invoking <tt class="literal"><span class="pre">operator++()</span></tt> moves the base
|
|
iterator backward and invoking <tt class="literal"><span class="pre">operator--()</span></tt> moves the base
|
|
iterator forward.</blockquote>
|
|
<p>to:</p>
|
|
<blockquote class="last">
|
|
The reverse iterator adaptor iterates through the adapted iterator
|
|
range in the opposite direction.</blockquote>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="prior-is-undefined">
|
|
<h2><a class="toc-backref" href="#id11" name="prior-is-undefined">9.10 'prior' is undefined</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>reverse_iterator::dereference is specified as calling a function
|
|
named 'prior' which has no specification.</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">Change the specification to avoid using <tt class="literal"><span class="pre">prior</span></tt> as follows.</p>
|
|
<p>Remove:</p>
|
|
<pre class="literal-block">
|
|
typename reverse_iterator::reference dereference() const { return *prior(this->base()); }
|
|
</pre>
|
|
<p>And at the end of the operations section add:</p>
|
|
<blockquote class="last">
|
|
<p><tt class="literal"><span class="pre">reference</span> <span class="pre">operator*()</span> <span class="pre">const;</span></tt></p>
|
|
<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">Effects:</th><td class="field-body"></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<pre class="literal-block">
|
|
Iterator tmp = m_iterator;
|
|
return *--tmp;
|
|
</pre>
|
|
</blockquote>
|
|
</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Rationale:</th><td class="field-body">The style of specification has changed because of issue 9.37x.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="in-other-words-is-bad-wording">
|
|
<h2><a class="toc-backref" href="#id12" name="in-other-words-is-bad-wording">9.11 "In other words" is bad wording</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>Transform iterator has a two-part specification: it does this, in
|
|
other words, it does that. "In other words" always means "I didn't
|
|
say it right, so I'll try again." We need to say it once.</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">Change:</p>
|
|
<blockquote>
|
|
The transform iterator adapts an iterator by applying some function
|
|
object to the result of dereferencing the iterator. In other words,
|
|
the <tt class="literal"><span class="pre">operator*</span></tt> of the transform iterator first dereferences the
|
|
base iterator, passes the result of this to the function object, and
|
|
then returns the result.</blockquote>
|
|
<p>to:</p>
|
|
<blockquote class="last">
|
|
The transform iterator adapts an iterator by modifying the
|
|
<tt class="literal"><span class="pre">operator*</span></tt> to apply a function object to the result of
|
|
dereferencing the iterator and returning the result.</blockquote>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="transform-iterator-shouldn-t-mandate-private-member">
|
|
<h2><a class="toc-backref" href="#id13" name="transform-iterator-shouldn-t-mandate-private-member">9.12 Transform_iterator shouldn't mandate private member</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>transform_iterator has a private member named 'm_f' which should be
|
|
marked "exposition only."</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">Mark the member <tt class="literal"><span class="pre">m_f</span></tt> as exposition
|
|
only. Note/DWA: I think this is NAD because the user can't
|
|
detect it, though I'm happy to mark it exposition only.</p>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
UnaryFunction m_f;
|
|
</pre>
|
|
<p>to:</p>
|
|
<pre class="last literal-block">
|
|
UnaryFunction m_f; // exposition only
|
|
</pre>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="unclear-description-of-counting-iterator">
|
|
<h2><a class="toc-backref" href="#id14" name="unclear-description-of-counting-iterator">9.13 Unclear description of counting iterator</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>The description of Counting iterator is unclear. "The counting
|
|
iterator adaptor implements dereference by returning a reference to
|
|
the base object. The other operations are implemented by the base
|
|
m_iterator, as per the inheritance from iterator_adaptor."</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">Change:</p>
|
|
<blockquote>
|
|
The counting iterator adaptor implements dereference by
|
|
returning a reference to the base object. The other operations
|
|
are implemented by the base <tt class="literal"><span class="pre">m_iterator</span></tt>, as per the
|
|
inheritance from <tt class="literal"><span class="pre">iterator_adaptor</span></tt>.</blockquote>
|
|
<p>to:</p>
|
|
<blockquote class="last">
|
|
<tt class="literal"><span class="pre">counting_iterator</span></tt> adapts an object by adding an
|
|
<tt class="literal"><span class="pre">operator*</span></tt> that returns the current value of the object. All
|
|
other iterator operations are forwarded to the adapted object.</blockquote>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="counting-iterator-s-difference-type">
|
|
<h2><a class="toc-backref" href="#id15" name="counting-iterator-s-difference-type">9.14 Counting_iterator's difference type</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>Counting iterator has the following note:</p>
|
|
<blockquote>
|
|
[Note: implementers are encouraged to provide an implementation
|
|
of distance_to and a difference_type that avoids overflows in the
|
|
cases when the Incrementable type is a numeric type.]</blockquote>
|
|
<p>I'm not sure what this means. The user provides a template argument
|
|
named Difference, but there's no difference_type. I assume this is
|
|
just a glitch in the wording. But if implementors are encouraged to
|
|
ignore this argument if it won't work right, why is it there?</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body">The <tt class="literal"><span class="pre">difference_type</span></tt> was inherited from
|
|
<tt class="literal"><span class="pre">iterator_adaptor</span></tt>. However, we've removed the explicit
|
|
inheritance, so explicit typedefs have been added. See the
|
|
resolution of 9.37x.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="how-to-detect-lvalueness">
|
|
<h2><a class="toc-backref" href="#id16" name="how-to-detect-lvalueness">9.15 How to detect lvalueness?</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Dave Abrahams</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>Shortly after N1550 was accepted, we discovered that an iterator's
|
|
lvalueness can be determined knowing only its value_type. This
|
|
predicate can be calculated even for old-style iterators (on whose
|
|
reference 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 T& function template
|
|
parameter. Similarly, it is possible to detect an iterator's
|
|
readability knowing only its value_type. Thus, any interface which
|
|
asks the user to explicitly describe an iterator's lvalue-ness or
|
|
readability seems to introduce needless complexity.</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><ol class="first arabic simple">
|
|
<li>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.</li>
|
|
<li>Change the <tt class="literal"><span class="pre">is_readable</span></tt> specification. Remove the
|
|
requirement for support of the <tt class="literal"><span class="pre">is_readable</span></tt> trait from the
|
|
Readable Iterator concept.</li>
|
|
<li>Remove the <tt class="literal"><span class="pre">iterator_tag</span></tt> class and transplant the logic for
|
|
choosing an iterator category into <tt class="literal"><span class="pre">iterator_facade</span></tt>.</li>
|
|
<li>Change the specification of <tt class="literal"><span class="pre">traversal_category</span></tt>.</li>
|
|
<li>Remove Access parameters from N1530</li>
|
|
</ol>
|
|
<p>In N1550:</p>
|
|
<p>Remove:</p>
|
|
<blockquote>
|
|
<p>Since the access concepts are not related via refinement, but
|
|
instead cover orthogonal issues, we do not use tags for the
|
|
access concepts, but instead use the equivalent of a bit field.</p>
|
|
<p>We provide an access mechanism for mapping iterator types to
|
|
the new traversal tags and access bit field. Our design reuses
|
|
<tt class="literal"><span class="pre">iterator_traits<Iter>::iterator_category</span></tt> as the access
|
|
mechanism. To that end, the access and traversal information is
|
|
bundled into a single type using the following <cite>iterator_tag</cite>
|
|
class.</p>
|
|
<pre class="literal-block">
|
|
enum iterator_access { readable_iterator = 1, writable_iterator = 2,
|
|
swappable_iterator = 4, lvalue_iterator = 8 };
|
|
|
|
template <unsigned int access_bits, class TraversalTag>
|
|
struct iterator_tag : /* appropriate old category or categories */ {
|
|
static const iterator_access access =
|
|
(iterator_access)access_bits &
|
|
(readable_iterator | writable_iterator | swappable_iterator);
|
|
typedef TraversalTag traversal;
|
|
};
|
|
</pre>
|
|
<p>The <tt class="literal"><span class="pre">access_bits</span></tt> argument is declared to be <tt class="literal"><span class="pre">unsigned</span> <span class="pre">int</span></tt>
|
|
instead of the enum <tt class="literal"><span class="pre">iterator_access</span></tt> for convenience of
|
|
use. For example, the expression <tt class="literal"><span class="pre">(readable_iterator</span> <span class="pre">|</span>
|
|
<span class="pre">writable_iterator)</span></tt> produces an unsigned int, not an
|
|
<tt class="literal"><span class="pre">iterator_access</span></tt>. The purpose of the <tt class="literal"><span class="pre">lvalue_iterator</span></tt>
|
|
part of the <tt class="literal"><span class="pre">iterator_access</span></tt> enum is to communicate to
|
|
<tt class="literal"><span class="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 <tt class="literal"><span class="pre">lvalue_iterator</span></tt> bit is not recorded in the
|
|
<tt class="literal"><span class="pre">iterator_tag::access</span></tt> data member.</p>
|
|
<p>The <tt class="literal"><span class="pre">iterator_tag</span></tt> class template is derived from the
|
|
appropriate iterator tag or tags from the old requirements
|
|
based on the access bits and traversal tag passed as template
|
|
parameters. The algorithm for determining the old tag or tags
|
|
picks the least refined old concepts that include all of the
|
|
requirements of the access and traversal concepts (that is, the
|
|
closest fit), if any such category exists. For example, the
|
|
category tag for a Readable Single Pass Iterator will always be
|
|
derived from <tt class="literal"><span class="pre">input_iterator_tag</span></tt>, while the category tag for
|
|
a Single Pass Iterator that is both Readable and Writable will
|
|
be derived from both <tt class="literal"><span class="pre">input_iterator_tag</span></tt> and
|
|
<tt class="literal"><span class="pre">output_iterator_tag</span></tt>.</p>
|
|
<p>We also provide several helper classes that make it convenient
|
|
to obtain the access and traversal characteristics of an
|
|
iterator. These helper classes work both for iterators whose
|
|
<tt class="literal"><span class="pre">iterator_category</span></tt> is <tt class="literal"><span class="pre">iterator_tag</span></tt> and also for
|
|
iterators using the original iterator categories.</p>
|
|
<pre class="literal-block">
|
|
template <class Iterator> struct is_readable { typedef ... type; };
|
|
template <class Iterator> struct is_writable { typedef ... type; };
|
|
template <class Iterator> struct is_swappable { typedef ... type; };
|
|
template <class Iterator> struct traversal_category { typedef ... type; };
|
|
</pre>
|
|
</blockquote>
|
|
<p>After:</p>
|
|
<blockquote>
|
|
Like the old iterator requirements, we provide tags for
|
|
purposes of dispatching based on the traversal concepts. The
|
|
tags are related via inheritance so that a tag is convertible
|
|
to another tag if the concept associated with the first tag is
|
|
a refinement of the second tag.</blockquote>
|
|
<p>Add:</p>
|
|
<blockquote>
|
|
<p>Our design reuses <tt class="literal"><span class="pre">iterator_traits<Iter>::iterator_category</span></tt>
|
|
to indicate an iterator's traversal capability. To specify
|
|
capabilities not captured by any old-style iterator category,
|
|
an iterator designer can use an <tt class="literal"><span class="pre">iterator_category</span></tt> type that
|
|
is convertible to both the the most-derived old iterator
|
|
category tag which fits, and the appropriate new iterator
|
|
traversal tag.</p>
|
|
<p>We do not provide tags for the purposes of dispatching based on
|
|
the access concepts, in part because we could not find a way to
|
|
automatically infer the right access tags for old-style
|
|
iterators. An iterator's writability may be dependent on the
|
|
assignability of its <tt class="literal"><span class="pre">value_type</span></tt> and there's no known way to
|
|
detect whether an arbitrary type is assignable. Fortunately,
|
|
the need for dispatching based on access capability is not as
|
|
great as the need for dispatching based on traversal
|
|
capability.</p>
|
|
</blockquote>
|
|
<p>From the Readable Iterator Requirements table, remove:</p>
|
|
<blockquote>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="37%" />
|
|
<col width="37%" />
|
|
<col width="26%" />
|
|
</colgroup>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">is_readable<X>::type</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">true_type</span></tt></td>
|
|
<td> </td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>From the Writable Iterator Requirements table, remove:</p>
|
|
<blockquote>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="37%" />
|
|
<col width="21%" />
|
|
<col width="42%" />
|
|
</colgroup>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">is_writable<X>::type</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">true_type</span></tt></td>
|
|
<td> </td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>From the Swappable Iterator Requirements table, remove:</p>
|
|
<blockquote>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="37%" />
|
|
<col width="19%" />
|
|
<col width="43%" />
|
|
</colgroup>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">is_swappable<X>::type</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">true_type</span></tt></td>
|
|
<td> </td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>From [lib.iterator.synopsis] replace:</p>
|
|
<pre class="literal-block">
|
|
template <class Iterator> struct is_readable;
|
|
template <class Iterator> struct is_writable;
|
|
template <class Iterator> struct is_swappable;
|
|
template <class Iterator> struct traversal_category;
|
|
|
|
enum iterator_access { readable_iterator = 1, writable_iterator = 2,
|
|
swappable_iterator = 4, lvalue_iterator = 8 };
|
|
|
|
template <unsigned int access_bits, class TraversalTag>
|
|
struct iterator_tag : /* appropriate old category or categories */ {
|
|
static const iterator_access access =
|
|
(iterator_access)access_bits &
|
|
(readable_iterator | writable_iterator | swappable_iterator);
|
|
typedef TraversalTag traversal;
|
|
};
|
|
</pre>
|
|
<p>with:</p>
|
|
<pre class="literal-block">
|
|
template <class Iterator> struct is_readable_iterator;
|
|
template <class Iterator> struct iterator_traversal;
|
|
</pre>
|
|
<p>In [lib.iterator.traits], remove:</p>
|
|
<blockquote>
|
|
<p>The <tt class="literal"><span class="pre">iterator_tag</span></tt> class template is an iterator category tag
|
|
that encodes the access enum and traversal tag in addition to
|
|
being compatible with the original iterator tags. The
|
|
<tt class="literal"><span class="pre">iterator_tag</span></tt> class inherits from one of the original
|
|
iterator tags according to the following pseudo-code.</p>
|
|
<pre class="literal-block">
|
|
inherit-category(access, traversal-tag) =
|
|
if ((access & readable_iterator) && (access & lvalue_iterator)) {
|
|
if (traversal-tag is convertible to random_access_traversal_tag)
|
|
return random_access_iterator_tag;
|
|
else if (traversal-tag is convertible to bidirectional_traversal_tag)
|
|
return bidirectional_iterator_tag;
|
|
else if (traversal-tag is convertible to forward_traversal_tag)
|
|
return forward_iterator_tag;
|
|
else if (traversal-tag is convertible to single_pass_traversal_tag)
|
|
if (access-tag is convertible to writable_iterator_tag)
|
|
return input_output_iterator_tag;
|
|
else
|
|
return input_iterator_tag;
|
|
else
|
|
return null_category_tag;
|
|
} else if ((access & readable_iterator) and (access & writable_iterator)
|
|
and traversal-tag is convertible to single_pass_iterator_tag)
|
|
return input_output_iterator_tag;
|
|
else if (access & readable_iterator
|
|
and traversal-tag is convertible to single_pass_iterator_tag)
|
|
return input_iterator_tag;
|
|
else if (access & writable_iterator
|
|
and traversal-tag is convertible to incrementable_iterator_tag)
|
|
return output_iterator_tag;
|
|
else
|
|
return null_category_tag;
|
|
</pre>
|
|
<p>If the argument for <tt class="literal"><span class="pre">TraversalTag</span></tt> is not convertible to
|
|
<tt class="literal"><span class="pre">incrementable_iterator_tag</span></tt> then the program is ill-formed.</p>
|
|
</blockquote>
|
|
<p>Change:</p>
|
|
<blockquote>
|
|
<p>The <tt class="literal"><span class="pre">is_readable</span></tt>, <tt class="literal"><span class="pre">is_writable</span></tt>, <tt class="literal"><span class="pre">is_swappable</span></tt>, and
|
|
<tt class="literal"><span class="pre">traversal_category</span></tt> class templates are traits classes. For
|
|
iterators whose <tt class="literal"><span class="pre">iterator_traits<Iter>::iterator_category</span></tt>
|
|
type is <tt class="literal"><span class="pre">iterator_tag</span></tt>, these traits obtain the <tt class="literal"><span class="pre">access</span></tt>
|
|
enum and <tt class="literal"><span class="pre">traversal</span></tt> member type from within
|
|
<tt class="literal"><span class="pre">iterator_tag</span></tt>. For iterators whose
|
|
<tt class="literal"><span class="pre">iterator_traits<Iter>::iterator_category</span></tt> type is not
|
|
<tt class="literal"><span class="pre">iterator_tag</span></tt> and instead is a tag convertible to one of the
|
|
original tags, the appropriate traversal tag and access bits
|
|
are deduced. The following pseudo-code describes the
|
|
algorithm.</p>
|
|
<pre class="literal-block">
|
|
is-readable(Iterator) =
|
|
cat = iterator_traits<Iterator>::iterator_category;
|
|
if (cat == iterator_tag<Access,Traversal>)
|
|
return Access & readable_iterator;
|
|
else if (cat is convertible to input_iterator_tag)
|
|
return true;
|
|
else
|
|
return false;
|
|
|
|
is-writable(Iterator) =
|
|
cat = iterator_traits<Iterator>::iterator_category;
|
|
if (cat == iterator_tag<Access,Traversal>)
|
|
return Access & writable_iterator;
|
|
else 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;
|
|
|
|
is-swappable(Iterator) =
|
|
cat = iterator_traits<Iterator>::iterator_category;
|
|
if (cat == iterator_tag<Access,Traversal>)
|
|
return Access & swappable_iterator;
|
|
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;
|
|
|
|
traversal-category(Iterator) =
|
|
cat = iterator_traits<Iterator>::iterator_category;
|
|
if (cat == iterator_tag<Access,Traversal>)
|
|
return Traversal;
|
|
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>
|
|
<p>The following specializations provide the access and traversal
|
|
category tags for pointer types.</p>
|
|
<pre class="literal-block">
|
|
template <typename T>
|
|
struct is_readable<const T*> { typedef true_type type; };
|
|
template <typename T>
|
|
struct is_writable<const T*> { typedef false_type type; };
|
|
template <typename T>
|
|
struct is_swappable<const T*> { typedef false_type type; };
|
|
|
|
template <typename T>
|
|
struct is_readable<T*> { typedef true_type type; };
|
|
template <typename T>
|
|
struct is_writable<T*> { typedef true_type type; };
|
|
template <typename T>
|
|
struct is_swappable<T*> { typedef true_type type; };
|
|
|
|
template <typename T>
|
|
struct traversal_category<T*>
|
|
{
|
|
typedef random_access_traversal_tag type;
|
|
};
|
|
</pre>
|
|
</blockquote>
|
|
<p>to:</p>
|
|
<blockquote>
|
|
<p>The <tt class="literal"><span class="pre">is_readable_iterator</span></tt> class template satisfies the
|
|
UnaryTypeTrait requirements.</p>
|
|
<p>Given an iterator type <tt class="literal"><span class="pre">X</span></tt>,
|
|
<tt class="literal"><span class="pre">is_readable_iterator<X>::value</span></tt> yields <tt class="literal"><span class="pre">true</span></tt> if, for an
|
|
object <tt class="literal"><span class="pre">a</span></tt> of type <tt class="literal"><span class="pre">X</span></tt>, <tt class="literal"><span class="pre">*a</span></tt> is convertible to
|
|
<tt class="literal"><span class="pre">iterator_traits<X>::value_type</span></tt>, and <tt class="literal"><span class="pre">false</span></tt> otherwise.</p>
|
|
<a class="target" id="category-to-traversal" name="category-to-traversal"></a><p><tt class="literal"><span class="pre">iterator_traversal<X>::type</span></tt> is</p>
|
|
<pre class="literal-block">
|
|
<em>category-to-traversal</em>(iterator_traits<X>::iterator_category)
|
|
</pre>
|
|
<p>where <em>category-to-traversal</em> is defined as follows</p>
|
|
<pre class="literal-block">
|
|
<em>category-to-traversal</em>(C) =
|
|
if (C is convertible to incrementable_traversal_tag)
|
|
return C;
|
|
else if (C is convertible to random_access_iterator_tag)
|
|
return random_access_traversal_tag;
|
|
else if (C is convertible to bidirectional_iterator_tag)
|
|
return bidirectional_traversal_tag;
|
|
else if (C is convertible to forward_iterator_tag)
|
|
return forward_traversal_tag;
|
|
else if (C is convertible to input_iterator_tag)
|
|
return single_pass_traversal_tag;
|
|
else if (C is convertible to output_iterator_tag)
|
|
return incrementable_traversal_tag;
|
|
else
|
|
<em>the program is ill-formed</em>
|
|
</pre>
|
|
</blockquote>
|
|
<p>In N1530:</p>
|
|
<p>In [lib.iterator.helper.synopsis]:</p>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
const unsigned use_default_access = -1;
|
|
|
|
struct iterator_core_access { /* implementation detail */ };
|
|
|
|
template <
|
|
class Derived
|
|
, class Value
|
|
, unsigned AccessCategory
|
|
, class TraversalCategory
|
|
, class Reference = Value&
|
|
, class Difference = ptrdiff_t
|
|
>
|
|
class iterator_facade;
|
|
|
|
template <
|
|
class Derived
|
|
, class Base
|
|
, class Value = use_default
|
|
, unsigned Access = use_default_access
|
|
, class Traversal = use_default
|
|
, class Reference = use_default
|
|
, class Difference = use_default
|
|
>
|
|
class iterator_adaptor;
|
|
|
|
template <
|
|
class Iterator
|
|
, class Value = use_default
|
|
, unsigned Access = use_default_access
|
|
, class Traversal = use_default
|
|
, class Reference = use_default
|
|
, class Difference = use_default
|
|
>
|
|
class indirect_iterator;
|
|
</pre>
|
|
<p>To:</p>
|
|
<pre class="literal-block">
|
|
struct iterator_core_access { /* implementation detail */ };
|
|
|
|
template <
|
|
class Derived
|
|
, class Value
|
|
, class CategoryOrTraversal
|
|
, class Reference = Value&
|
|
, class Difference = ptrdiff_t
|
|
>
|
|
class iterator_facade;
|
|
|
|
template <
|
|
class Derived
|
|
, class Base
|
|
, class Value = use_default
|
|
, class CategoryOrTraversal = use_default
|
|
, class Reference = use_default
|
|
, class Difference = use_default
|
|
>
|
|
class iterator_adaptor;
|
|
|
|
template <
|
|
class Iterator
|
|
, class Value = use_default
|
|
, class CategoryOrTraversal = use_default
|
|
, class Reference = use_default
|
|
, class Difference = use_default
|
|
>
|
|
class indirect_iterator;
|
|
</pre>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
template <
|
|
class Incrementable
|
|
, unsigned Access = use_default_access
|
|
, class Traversal = use_default
|
|
, class Difference = use_default
|
|
>
|
|
class counting_iterator
|
|
</pre>
|
|
<p>To:</p>
|
|
<pre class="literal-block">
|
|
template <
|
|
class Incrementable
|
|
, class CategoryOrTraversal = use_default
|
|
, class Difference = use_default
|
|
>
|
|
class counting_iterator;
|
|
</pre>
|
|
<p>In [lib.iterator.facade]:</p>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
template <
|
|
class Derived
|
|
, class Value
|
|
, unsigned AccessCategory
|
|
, class TraversalCategory
|
|
, class Reference = /* see below */
|
|
, class Difference = ptrdiff_t
|
|
>
|
|
class iterator_facade {
|
|
</pre>
|
|
<p>to:</p>
|
|
<pre class="literal-block">
|
|
template <
|
|
class Derived
|
|
, class Value
|
|
, class CategoryOrTraversal
|
|
, class Reference = Value&
|
|
, class Difference = ptrdiff_t
|
|
>
|
|
class iterator_facade {
|
|
</pre>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
typedef iterator_tag<AccessCategory, TraversalCategory> iterator_category;
|
|
</pre>
|
|
<p>to:</p>
|
|
<pre class="literal-block">
|
|
typedef /* see below */ iterator_category;
|
|
</pre>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
// Comparison operators
|
|
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
|
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
|
typename enable_if_interoperable<Dr1, Dr2, bool>::type // exposition
|
|
operator ==(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
|
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
|
|
|
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
|
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
|
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
|
operator !=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
|
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
|
|
|
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
|
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
|
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
|
operator <(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
|
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
|
|
|
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
|
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
|
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
|
operator <=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
|
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
|
|
|
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
|
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
|
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
|
operator >(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
|
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
|
|
|
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
|
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
|
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
|
operator >=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
|
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
|
|
|
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
|
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
|
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
|
operator >=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
|
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
|
|
|
// Iterator difference
|
|
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
|
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
|
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
|
operator -(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
|
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
|
|
|
// Iterator addition
|
|
template <class Derived, class V, class AC, class TC, class R, class D>
|
|
Derived operator+ (iterator_facade<Derived, V, AC, TC, R, D> const&,
|
|
typename Derived::difference_type n)
|
|
</pre>
|
|
<p>to:</p>
|
|
<pre class="literal-block">
|
|
// Comparison operators
|
|
template <class Dr1, class V1, class TC1, class R1, class D1,
|
|
class Dr2, class V2, class TC2, class R2, class D2>
|
|
typename enable_if_interoperable<Dr1,Dr2,bool>::type // exposition
|
|
operator ==(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
|
|
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
|
|
|
template <class Dr1, class V1, class TC1, class R1, class D1,
|
|
class Dr2, class V2, class TC2, class R2, class D2>
|
|
typename enable_if_interoperable<Dr1,Dr2,bool>::type
|
|
operator !=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
|
|
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
|
|
|
template <class Dr1, class V1, class TC1, class R1, class D1,
|
|
class Dr2, class V2, class TC2, class R2, class D2>
|
|
typename enable_if_interoperable<Dr1,Dr2,bool>::type
|
|
operator <(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
|
|
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
|
|
|
template <class Dr1, class V1, class TC1, class R1, class D1,
|
|
class Dr2, class V2, class TC2, class R2, class D2>
|
|
typename enable_if_interoperable<Dr1,Dr2,bool>::type
|
|
operator <=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
|
|
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
|
|
|
template <class Dr1, class V1, class TC1, class R1, class D1,
|
|
class Dr2, class V2, class TC2, class R2, class D2>
|
|
typename enable_if_interoperable<Dr1,Dr2,bool>::type
|
|
operator >(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
|
|
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
|
|
|
template <class Dr1, class V1, class TC1, class R1, class D1,
|
|
class Dr2, class V2, class TC2, class R2, class D2>
|
|
typename enable_if_interoperable<Dr1,Dr2,bool>::type
|
|
operator >=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
|
|
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
|
|
|
// Iterator difference
|
|
template <class Dr1, class V1, class TC1, class R1, class D1,
|
|
class Dr2, class V2, class TC2, class R2, class D2>
|
|
/* see below */
|
|
operator-(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
|
|
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
|
|
|
// Iterator addition
|
|
template <class Dr, class V, class TC, class R, class D>
|
|
Derived operator+ (iterator_facade<Dr,V,TC,R,D> const&,
|
|
typename Derived::difference_type n);
|
|
|
|
template <class Dr, class V, class TC, class R, class D>
|
|
Derived operator+ (typename Derived::difference_type n,
|
|
iterator_facade<Dr,V,TC,R,D> const&);
|
|
</pre>
|
|
<p>After the <tt class="literal"><span class="pre">iterator_facade</span></tt> synopsis, add:</p>
|
|
<p>The <tt class="literal"><span class="pre">iterator_category</span></tt> member of <tt class="literal"><span class="pre">iterator_facade</span></tt> is</p>
|
|
<pre class="literal-block">
|
|
<em>iterator-category</em>(CategoryOrTraversal, value_type, reference)
|
|
</pre>
|
|
<p>where <em>iterator-category</em> is defined as follows:</p>
|
|
<pre class="last literal-block">
|
|
<em>iterator-category</em>(C,R,V) :=
|
|
if (C is convertible to std::input_iterator_tag
|
|
|| C is convertible to std::output_iterator_tag
|
|
)
|
|
return C
|
|
|
|
else if (C is not convertible to incrementable_traversal_tag)
|
|
<em>the program is ill-formed</em>
|
|
|
|
else return a type X satisfying the following two constraints:
|
|
|
|
1. X is convertible to X1, and not to any more-derived
|
|
type, where X1 is defined by:
|
|
|
|
if (R is a reference type
|
|
&& C is convertible to forward_traversal_tag)
|
|
{
|
|
if (C is convertible to random_access_traversal_tag)
|
|
X1 = random_access_iterator_tag
|
|
else if (C is convertible to bidirectional_traversal_tag)
|
|
X1 = bidirectional_iterator_tag
|
|
else
|
|
X1 = forward_iterator_tag
|
|
}
|
|
else
|
|
{
|
|
if (C is convertible to single_pass_traversal_tag
|
|
&& R is convertible to V)
|
|
X1 = input_iterator_tag
|
|
else
|
|
X1 = C
|
|
}
|
|
|
|
2. <a class="reference" href="#category-to-traversal"><em>category-to-traversal</em></a>(X) is convertible to the most
|
|
derived traversal tag type to which X is also
|
|
convertible, and not to any more-derived traversal tag
|
|
type.
|
|
</pre>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<a class="target" id="iterator-category" name="iterator-category"></a><blockquote>
|
|
<p>In [lib.iterator.facade] <tt class="literal"><span class="pre">iterator_facade</span></tt> requirements:</p>
|
|
<p>Remove:</p>
|
|
<blockquote>
|
|
<tt class="literal"><span class="pre">AccessCategory</span></tt> must be an unsigned value which uses no more
|
|
bits than the greatest value of <tt class="literal"><span class="pre">iterator_access</span></tt>.</blockquote>
|
|
<p>In the <strong>Iterator Adaptor</strong> section, change:</p>
|
|
<blockquote>
|
|
Several of the template parameters of <tt class="literal"><span class="pre">iterator_adaptor</span></tt> default
|
|
to <tt class="literal"><span class="pre">use_default</span></tt> (or <tt class="literal"><span class="pre">use_default_access</span></tt>).</blockquote>
|
|
<p>to:</p>
|
|
<blockquote>
|
|
Several of the template parameters of <tt class="literal"><span class="pre">iterator_adaptor</span></tt> default
|
|
to <tt class="literal"><span class="pre">use_default</span></tt>.</blockquote>
|
|
<p>In [lib.iterator.special.adaptors]:</p>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
template <
|
|
class Iterator
|
|
, class Value = use_default
|
|
, unsigned Access = use_default_access
|
|
, class Traversal = use_default
|
|
, class Reference = use_default
|
|
, class Difference = use_default
|
|
>
|
|
class indirect_iterator
|
|
</pre>
|
|
<p>to:</p>
|
|
<pre class="literal-block">
|
|
template <
|
|
class Iterator
|
|
, class Value = use_default
|
|
, class CategoryOrTraversal = use_default
|
|
, class Reference = use_default
|
|
, class Difference = use_default
|
|
>
|
|
class indirect_iterator
|
|
</pre>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
template <
|
|
class Iterator2, class Value2, unsigned Access2, class Traversal2
|
|
, class Reference2, class Difference2
|
|
>
|
|
indirect_iterator(
|
|
</pre>
|
|
<p>to:</p>
|
|
<pre class="literal-block">
|
|
template <
|
|
class Iterator2, class Value2, class Category2
|
|
, class Reference2, class Difference2
|
|
>
|
|
indirect_iterator(
|
|
</pre>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
template <
|
|
class Incrementable
|
|
, unsigned Access = use_default_access
|
|
, class Traversal = use_default
|
|
, class Difference = use_default
|
|
>
|
|
class counting_iterator
|
|
</pre>
|
|
<p>to:</p>
|
|
<pre class="literal-block">
|
|
template <
|
|
class Incrementable
|
|
, class CategoryOrTraversal = use_default
|
|
, class Difference = use_default
|
|
>
|
|
class counting_iterator
|
|
</pre>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
typedef iterator_tag<
|
|
writable_iterator
|
|
, incrementable_traversal_tag
|
|
> iterator_category;
|
|
</pre>
|
|
<p>to:</p>
|
|
<blockquote>
|
|
typedef std::output_iterator_tag iterator_category;</blockquote>
|
|
<p>In [lib.iterator.adaptor]</p>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
template <
|
|
class Derived
|
|
, class Base
|
|
, class Value = use_default
|
|
, unsigned Access = use_default_access
|
|
, class Traversal = use_default
|
|
, class Reference = use_default
|
|
, class Difference = use_default
|
|
>
|
|
class iterator_adaptor
|
|
</pre>
|
|
<p>To:</p>
|
|
<pre class="literal-block">
|
|
template <
|
|
class Derived
|
|
, class Base
|
|
, class Value = use_default
|
|
, class CategoryOrTraversal = use_default
|
|
, class Reference = use_default
|
|
, class Difference = use_default
|
|
>
|
|
class iterator_adaptor
|
|
</pre>
|
|
</blockquote>
|
|
<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">Rationale:</th><td class="field-body"></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<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 class="section" id="is-writable-iterator-returns-false-positives">
|
|
<h2><a class="toc-backref" href="#id17" name="is-writable-iterator-returns-false-positives">9.16 is_writable_iterator returns false positives</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Dave Abrahams</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>is_writable_iterator returns false positives for forward iterators
|
|
whose value_type has a private assignment operator, or whose
|
|
reference type is not a reference (currently legal).</p>
|
|
<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" colspan="2">Proposed Resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body">See the resolution to 9.15.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="is-swappable-iterator-returns-false-positives">
|
|
<h2><a class="toc-backref" href="#id18" name="is-swappable-iterator-returns-false-positives">9.17 is_swappable_iterator returns false positives</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Dave Abrahams</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>is_swappable_iterator has the same problems as
|
|
is_writable_iterator. In addition, if we allow users to write their
|
|
own iter_swap functions it's easy to imagine old-style iterators
|
|
for which is_swappable returns false negatives.</p>
|
|
<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" colspan="2">Proposed Resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body">See the resolution to 9.15.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="are-is-readable-is-writable-and-is-swappable-useful">
|
|
<h2><a class="toc-backref" href="#id19" name="are-is-readable-is-writable-and-is-swappable-useful">9.18 Are is_readable, is_writable, and is_swappable useful?</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Dave Abrahams</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>I am concerned that there is little use for any of is_readable,
|
|
is_writable, or is_swappable, and that not only do they unduly
|
|
constrain iterator implementors but they add overhead to
|
|
iterator_facade and iterator_adaptor in the form of a template
|
|
parameter which would otherwise be unneeded. Since we can't
|
|
implement two of them accurately for old-style iterators, I am
|
|
having a hard time justifying their impact on the rest of the
|
|
proposal(s).</p>
|
|
<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" colspan="2">Proposed Resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body">See the resolution to 9.15.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="non-uniformity-of-the-lvalue-iterator-bit">
|
|
<h2><a class="toc-backref" href="#id20" name="non-uniformity-of-the-lvalue-iterator-bit">9.19 Non-Uniformity of the "lvalue_iterator Bit"</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Dave Abrahams</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>The proposed iterator_tag class template accepts an "access bits"
|
|
parameter which includes a bit to indicate the iterator's
|
|
lvalueness (whether its dereference operator returns a reference to
|
|
its value_type. The relevant part of N1550 says:</p>
|
|
<blockquote>
|
|
The purpose of the lvalue_iterator part of the iterator_access
|
|
enum is to communicate to iterator_tagwhether the reference type
|
|
is an lvalue so that the appropriate old category can be chosen
|
|
for the base class. The lvalue_iterator bit is not recorded in
|
|
the iterator_tag::access data member.</blockquote>
|
|
<p>The lvalue_iterator bit is not recorded because N1550 aims to
|
|
improve orthogonality of the iterator concepts, and a new-style
|
|
iterator's lvalueness is detectable by examining its reference
|
|
type. This inside/outside difference is awkward and confusing.</p>
|
|
<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" colspan="2">Proposed Resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body">The iterator_tag class will be removed, so this is no longer an issue.
|
|
See the resolution to 9.15.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="traversal-concepts-and-tags">
|
|
<h2><a class="toc-backref" href="#id21" name="traversal-concepts-and-tags">9.20 Traversal Concepts and Tags</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Dave Abrahams</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>Howard Hinnant pointed out some inconsistencies with the naming of
|
|
these tag types:</p>
|
|
<pre class="literal-block">
|
|
incrementable_iterator_tag // ++r, r++
|
|
single_pass_iterator_tag // adds a == b, a != b
|
|
forward_traversal_iterator_tag // adds multi-pass
|
|
bidirectional_traversal_iterator_tag // adds --r, r--
|
|
random_access_traversal_iterator_tag // adds r+n,n+r,etc.
|
|
</pre>
|
|
<p>Howard thought that it might be better if all tag names contained
|
|
the word "traversal". It's not clear that would result in the best
|
|
possible names, though. For example, incrementable iterators can
|
|
only make a single pass over their input. What really distinguishes
|
|
single pass iterators from incrementable iterators is not that they
|
|
can make a single pass, but that they are equality
|
|
comparable. Forward traversal iterators really distinguish
|
|
themselves by introducing multi-pass capability. Without entering
|
|
a "Parkinson's Bicycle Shed" type of discussion, it might be worth
|
|
giving the names of these tags (and the associated concepts) some
|
|
extra attention.</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">Change the names of the traversal tags to the
|
|
following names:</p>
|
|
<pre class="literal-block">
|
|
incrementable_traversal_tag
|
|
single_pass_traversal_tag
|
|
forward_traversal_tag
|
|
bidirectional_traversal_tag
|
|
random_access_traversal_tag
|
|
</pre>
|
|
<p>In [lib.iterator.traversal]:</p>
|
|
<p>Change:</p>
|
|
<blockquote>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="39%" />
|
|
<col width="37%" />
|
|
<col width="24%" />
|
|
</colgroup>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">traversal_category<X>::type</span></tt></td>
|
|
<td>Convertible to
|
|
<tt class="literal"><span class="pre">incrementable_iterator_tag</span></tt></td>
|
|
<td> </td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>to:</p>
|
|
<blockquote>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="39%" />
|
|
<col width="37%" />
|
|
<col width="24%" />
|
|
</colgroup>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">iterator_traversal<X>::type</span></tt></td>
|
|
<td>Convertible to
|
|
<tt class="literal"><span class="pre">incrementable_traversal_tag</span></tt></td>
|
|
<td> </td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>Change:</p>
|
|
<blockquote>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="36%" />
|
|
<col width="33%" />
|
|
<col width="31%" />
|
|
</colgroup>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">traversal_category<X>::type</span></tt></td>
|
|
<td>Convertible to
|
|
<tt class="literal"><span class="pre">single_pass_iterator_tag</span></tt></td>
|
|
<td> </td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>to:</p>
|
|
<blockquote>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="36%" />
|
|
<col width="33%" />
|
|
<col width="31%" />
|
|
</colgroup>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">iterator_traversal<X>::type</span></tt></td>
|
|
<td>Convertible to
|
|
<tt class="literal"><span class="pre">single_pass_traversal_tag</span></tt></td>
|
|
<td> </td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>Change:</p>
|
|
<blockquote>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="44%" />
|
|
<col width="39%" />
|
|
<col width="17%" />
|
|
</colgroup>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">traversal_category<X>::type</span></tt></td>
|
|
<td>Convertible to
|
|
<tt class="literal"><span class="pre">forward_traversal_iterator_tag</span></tt></td>
|
|
<td> </td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>to:</p>
|
|
<blockquote>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="38%" />
|
|
<col width="34%" />
|
|
<col width="27%" />
|
|
</colgroup>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">iterator_traversal<X>::type</span></tt></td>
|
|
<td>Convertible to
|
|
<tt class="literal"><span class="pre">forward_traversal_tag</span></tt></td>
|
|
<td> </td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>Change:</p>
|
|
<blockquote>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="35%" />
|
|
<col width="44%" />
|
|
<col width="21%" />
|
|
</colgroup>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">traversal_category<X>::type</span></tt></td>
|
|
<td>Convertible to
|
|
<tt class="literal"><span class="pre">bidirectional_traversal_iterator_tag</span></tt></td>
|
|
<td> </td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>to:</p>
|
|
<blockquote>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="38%" />
|
|
<col width="37%" />
|
|
<col width="25%" />
|
|
</colgroup>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">iterator_traversal<X>::type</span></tt></td>
|
|
<td>Convertible to
|
|
<tt class="literal"><span class="pre">bidirectional_traversal_tag</span></tt></td>
|
|
<td> </td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>Change:</p>
|
|
<blockquote>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="31%" />
|
|
<col width="35%" />
|
|
<col width="18%" />
|
|
<col width="16%" />
|
|
</colgroup>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">traversal_category<X>::type</span></tt></td>
|
|
<td>Convertible to
|
|
<tt class="literal"><span class="pre">random_access_traversal_iterator_tag</span></tt></td>
|
|
<td> </td>
|
|
<td> </td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>to:</p>
|
|
<blockquote>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="28%" />
|
|
<col width="30%" />
|
|
<col width="23%" />
|
|
<col width="20%" />
|
|
</colgroup>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">iterator_traversal<X>::type</span></tt></td>
|
|
<td>Convertible to
|
|
<tt class="literal"><span class="pre">random_access_traversal_tag</span></tt></td>
|
|
<td> </td>
|
|
<td> </td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>In [lib.iterator.synopsis], change:</p>
|
|
<pre class="literal-block">
|
|
struct incrementable_iterator_tag { };
|
|
struct single_pass_iterator_tag : incrementable_iterator_tag { };
|
|
struct forward_traversal_tag : single_pass_iterator_tag { };
|
|
</pre>
|
|
<p>to:</p>
|
|
<pre class="literal-block">
|
|
struct incrementable_traversal_tag { };
|
|
struct single_pass_traversal_tag : incrementable_traversal_tag { };
|
|
struct forward_traversal_tag : single_pass_traversal_tag { };
|
|
</pre>
|
|
<p>Remove:</p>
|
|
<pre class="last literal-block">
|
|
struct null_category_tag { };
|
|
struct input_output_iterator_tag : input_iterator_tag, output_iterator_tag {};
|
|
</pre>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="iterator-facade-derived-template-argument-underspecified">
|
|
<h2><a class="toc-backref" href="#id22" name="iterator-facade-derived-template-argument-underspecified">9.21 iterator_facade Derived template argument underspecified</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>The first template argument to iterator_facade is named Derived,
|
|
and the proposal says:</p>
|
|
<blockquote>
|
|
The Derived template parameter must be a class derived from
|
|
iterator_facade.</blockquote>
|
|
<p>First, iterator_facade is a template, so cannot be derived
|
|
from. Rather, the class must be derived from a specialization of
|
|
iterator_facade. More important, isn't Derived required to be the
|
|
class that is being defined? That is, if I understand it right, the
|
|
definition of D here this is not valid:</p>
|
|
<pre class="literal-block">
|
|
class C : public iterator_facade<C, ... > { ... };
|
|
class D : public iterator_facade<C, ...> { ... };
|
|
</pre>
|
|
<p>In the definition of D, the Derived argument to iterator_facade is
|
|
a class derived from a specialization of iterator_facade, so the
|
|
requirement is met. Shouldn't the requirement be more like "when
|
|
using iterator_facade to define an iterator class Iter, the class
|
|
Iter must be derived from a specialization of iterator_facade whose
|
|
first template argument is Iter." That's a bit awkward, but at the
|
|
moment I don't see a better way of phrasing it.</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">In [lib.iterator.facade]</p>
|
|
<p>Remove:</p>
|
|
<blockquote>
|
|
The <tt class="literal"><span class="pre">Derived</span></tt> template parameter must be a class derived from
|
|
<tt class="literal"><span class="pre">iterator_facade</span></tt>.</blockquote>
|
|
<p>Change:</p>
|
|
<blockquote>
|
|
The following table describes the other requirements on the
|
|
<tt class="literal"><span class="pre">Derived</span></tt> parameter. Depending on the resulting iterator's
|
|
<tt class="literal"><span class="pre">iterator_category</span></tt>, a subset of the expressions listed in the table
|
|
are required to be valid. The operations in the first column must be
|
|
accessible to member functions of class <tt class="literal"><span class="pre">iterator_core_access</span></tt>.</blockquote>
|
|
<p>to:</p>
|
|
<blockquote>
|
|
The following table describes the typical valid expressions on
|
|
<tt class="literal"><span class="pre">iterator_facade</span></tt>'s <tt class="literal"><span class="pre">Derived</span></tt> parameter, depending on the
|
|
iterator concept(s) it will model. The operations in the first
|
|
column must be made accessible to member functions of class
|
|
<tt class="literal"><span class="pre">iterator_core_access</span></tt>. In addition,
|
|
<tt class="literal"><span class="pre">static_cast<Derived*>(iterator_facade*)</span></tt> shall be well-formed.</blockquote>
|
|
<p>In [lib.iterator.adaptor]</p>
|
|
<p>Change:</p>
|
|
<blockquote>
|
|
The <tt class="literal"><span class="pre">iterator_adaptor</span></tt> is a base class template derived from
|
|
an instantiation of <tt class="literal"><span class="pre">iterator_facade</span></tt>.</blockquote>
|
|
<p>to:</p>
|
|
<blockquote>
|
|
Each specialization of the <tt class="literal"><span class="pre">iterator_adaptor</span></tt> class template
|
|
is derived from a specialization of <tt class="literal"><span class="pre">iterator_facade</span></tt>.</blockquote>
|
|
<p>Change:</p>
|
|
<blockquote>
|
|
The <tt class="literal"><span class="pre">Derived</span></tt> template parameter must be a derived class of
|
|
<tt class="literal"><span class="pre">iterator_adaptor</span></tt>.</blockquote>
|
|
<p>To:</p>
|
|
<blockquote class="last">
|
|
<tt class="literal"><span class="pre">static_cast<Derived*>(iterator_adaptor*)</span></tt> shall be well-formed.</blockquote>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>[Note: The proposed resolution to Issue 9.37 contains related
|
|
changes]</p>
|
|
</div>
|
|
<div class="section" id="return-type-of-iterator-difference-for-iterator-facade">
|
|
<h2><a class="toc-backref" href="#id23" name="return-type-of-iterator-difference-for-iterator-facade">9.22 return type of Iterator difference for iterator facade</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>The proposal says:</p>
|
|
<pre class="literal-block">
|
|
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
|
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
|
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
|
operator -(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
|
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
|
</pre>
|
|
<p>Shouldn't the return type be one of the two iterator types? Which
|
|
one? The idea is that if one of the iterator types can be converted
|
|
to the other type, then the subtraction is okay. Seems like the
|
|
return type should then be the type that was converted to. Is that
|
|
right?</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body">See resolution to 9.34.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="iterator-facade-minor-wording-issue">
|
|
<h2><a class="toc-backref" href="#id24" name="iterator-facade-minor-wording-issue">9.23 Iterator_facade: minor wording Issue</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>In the table that lists the required (sort of) member functions of
|
|
iterator types that are based on iterator_facade, the entry for
|
|
c.equal(y) says:</p>
|
|
<blockquote>
|
|
true iff c and y refer to the same position. Implements c == y
|
|
and c != y. The second sentence is inside out. c.equal(y) does
|
|
not implement either of these operations. It is used to implement
|
|
them. Same thing in the description of c.distance_to(z).</blockquote>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body">remove "implements" descriptions from
|
|
table. See resolution to 9.34</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="use-of-undefined-name-in-iterator-facade-table">
|
|
<h2><a class="toc-backref" href="#id25" name="use-of-undefined-name-in-iterator-facade-table">9.24 Use of undefined name in iterator_facade table</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>Several of the descriptions use the name X without defining
|
|
it. This seems to be a carryover from the table immediately above
|
|
this section, but the text preceding that table says "In the table
|
|
below, X is the derived iterator type." Looks like the X::
|
|
qualifiers aren't really needed; X::reference can simply be
|
|
reference, since that's defined by the iterator_facade
|
|
specialization itself.</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">Remove references to X.</p>
|
|
<p>In [lib.iterator.facade] operations <tt class="literal"><span class="pre">operator->()</span> <span class="pre">const;</span></tt>:</p>
|
|
<blockquote class="last">
|
|
<p>Change:</p>
|
|
<blockquote>
|
|
<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">Returns:</th><td class="field-body"><p class="first">If <tt class="literal"><span class="pre">X::reference</span></tt> is a reference type, an object
|
|
of type <tt class="literal"><span class="pre">X::pointer</span></tt> equal to:</p>
|
|
<pre class="literal-block">
|
|
&static_cast<Derived const*>(this)->dereference()
|
|
</pre>
|
|
<p>Otherwise returns an object of unspecified type such that,
|
|
given an object <tt class="literal"><span class="pre">a</span></tt> of type <tt class="literal"><span class="pre">X</span></tt>, <tt class="literal"><span class="pre">a->m</span></tt> is equivalent
|
|
to <tt class="literal"><span class="pre">(w</span> <span class="pre">=</span> <span class="pre">*a,</span> <span class="pre">w.m)</span></tt> for some temporary object <tt class="literal"><span class="pre">w</span></tt> of type
|
|
<tt class="literal"><span class="pre">X::value_type</span></tt>.</p>
|
|
<p class="last">The type <tt class="literal"><span class="pre">X::pointer</span></tt> is <tt class="literal"><span class="pre">Value*</span></tt> if
|
|
<tt class="literal"><span class="pre">is_writable_iterator<X>::value</span></tt> is <tt class="literal"><span class="pre">true</span></tt>, and
|
|
<tt class="literal"><span class="pre">Value</span> <span class="pre">const*</span></tt> otherwise.</p>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>to:</p>
|
|
<blockquote>
|
|
<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">Returns:</th><td class="field-body"><p class="first">If <tt class="literal"><span class="pre">reference</span></tt> is a reference type, an object
|
|
of type <tt class="literal"><span class="pre">pointer</span></tt> equal to:</p>
|
|
<pre class="literal-block">
|
|
&static_cast<Derived const*>(this)->dereference()
|
|
</pre>
|
|
<p class="last">Otherwise returns an object of unspecified type such that,
|
|
<tt class="literal"><span class="pre">(*static_cast<Derived</span> <span class="pre">const*>(this))->m</span></tt> is equivalent
|
|
to <tt class="literal"><span class="pre">(w</span> <span class="pre">=</span> <span class="pre">**static_cast<Derived</span> <span class="pre">const*>(this),</span> <span class="pre">w.m)</span></tt> for
|
|
some temporary object <tt class="literal"><span class="pre">w</span></tt> of type <tt class="literal"><span class="pre">value_type</span></tt>.</p>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>Further changes are covered by issue 9.26.</p>
|
|
</blockquote>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="iterator-facade-wrong-return-type">
|
|
<h2><a class="toc-backref" href="#id26" name="iterator-facade-wrong-return-type">9.25 Iterator_facade: wrong return type</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>Several of the member functions return a Derived object or a
|
|
Derived&. Their Effects clauses end with:</p>
|
|
<pre class="literal-block">
|
|
return *this;
|
|
</pre>
|
|
<p>This should be</p>
|
|
<pre class="literal-block">
|
|
return *static_cast<Derived*>(this);
|
|
</pre>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">In [lib.iterator.facade], in the effects clause
|
|
of the following operations:</p>
|
|
<pre class="literal-block">
|
|
Derived& operator++()
|
|
Derived& operator--()
|
|
Derived& operator+=(difference_type n)
|
|
Derived& operator-=(difference_type n)
|
|
</pre>
|
|
<dl class="last">
|
|
<dt>Change:</dt>
|
|
<dd><tt class="literal"><span class="pre">return</span> <span class="pre">*this</span></tt></dd>
|
|
<dt>to:</dt>
|
|
<dd><tt class="literal"><span class="pre">return</span> <span class="pre">*static_cast<Derived*>(this);</span></tt></dd>
|
|
</dl>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="iterator-facade-unclear-returns-clause-for-operator">
|
|
<h2><a class="toc-backref" href="#id27" name="iterator-facade-unclear-returns-clause-for-operator">9.26 Iterator_facade: unclear returns clause for operator[]</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>The returns clause for <tt class="literal"><span class="pre">operator[](difference_type</span> <span class="pre">n)</span></tt> const
|
|
says:</p>
|
|
<blockquote>
|
|
Returns: an object convertible to X::reference and holding a copy
|
|
p of a+n such that, for a constant object v of type
|
|
X::value_type, X::reference(a[n] = v) is equivalent to p = v.
|
|
This needs to define 'a', but assuming it's supposed to be
|
|
<tt class="literal"><span class="pre">*this</span></tt> (or maybe <tt class="literal"><span class="pre">*(Derived*)this</span></tt>), it still isn't clear
|
|
what this says. Presumably, the idea is that you can index off of
|
|
an iterator and assign to the result. But why the requirement
|
|
that it hold a copy of a+n? Granted, that's probably how it's
|
|
implemented, but it seems over-constrained. And the last phrase
|
|
seems wrong. p is an iterator; there's no requirement that you
|
|
can assign a value_type object to it. Should that be <tt class="literal"><span class="pre">*p</span> <span class="pre">=</span> <span class="pre">v</span></tt>?
|
|
But why the cast in reference(a[n] = v)?</blockquote>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">In section operator[]:</p>
|
|
<blockquote>
|
|
<p>Change:</p>
|
|
<blockquote>
|
|
Writable iterators built with <tt class="literal"><span class="pre">iterator_facade</span></tt> implement
|
|
the semantics required by the preferred resolution to <cite>issue
|
|
299</cite> and adopted by proposal <cite>n1477</cite>: the result of <tt class="literal"><span class="pre">p[n]</span></tt>
|
|
is a proxy object containing a copy of <tt class="literal"><span class="pre">p+n</span></tt>, and <tt class="literal"><span class="pre">p[n]</span> <span class="pre">=</span>
|
|
<span class="pre">x</span></tt> is equivalent to <tt class="literal"><span class="pre">*(p</span> <span class="pre">+</span> <span class="pre">n)</span> <span class="pre">=</span> <span class="pre">x</span></tt>. This approach will
|
|
work properly for any random-access iterator regardless of
|
|
the other details of its implementation. A user who knows
|
|
more about the implementation of her iterator is free to
|
|
implement an <tt class="literal"><span class="pre">operator[]</span></tt> which returns an lvalue in the
|
|
derived iterator class; it will hide the one supplied by
|
|
<tt class="literal"><span class="pre">iterator_facade</span></tt> from clients of her iterator.</blockquote>
|
|
<p>to:</p>
|
|
<blockquote>
|
|
Writable iterators built with <tt class="literal"><span class="pre">iterator_facade</span></tt> implement
|
|
the semantics required by the preferred resolution to <cite>issue
|
|
299</cite> and adopted by proposal <cite>n1550</cite>: the result of <tt class="literal"><span class="pre">p[n]</span></tt>
|
|
is an object convertible to the iterator's <tt class="literal"><span class="pre">value_type</span></tt>,
|
|
and <tt class="literal"><span class="pre">p[n]</span> <span class="pre">=</span> <span class="pre">x</span></tt> is equivalent to <tt class="literal"><span class="pre">*(p</span> <span class="pre">+</span> <span class="pre">n)</span> <span class="pre">=</span> <span class="pre">x</span></tt> (Note:
|
|
This result object may be implemented as a proxy containing a
|
|
copy of <tt class="literal"><span class="pre">p+n</span></tt>). This approach will work properly for any
|
|
random-access iterator regardless of the other details of its
|
|
implementation. A user who knows more about the
|
|
implementation of her iterator is free to implement an
|
|
<tt class="literal"><span class="pre">operator[]</span></tt> that returns an lvalue in the derived iterator
|
|
class; it will hide the one supplied by <tt class="literal"><span class="pre">iterator_facade</span></tt>
|
|
from clients of her iterator.</blockquote>
|
|
</blockquote>
|
|
<p>In [lib.iterator.facade] operations:</p>
|
|
<blockquote class="last">
|
|
<p>Change:</p>
|
|
<blockquote>
|
|
<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">Returns:</th><td class="field-body">an object convertible to <tt class="literal"><span class="pre">X::reference</span></tt> and
|
|
holding a copy <em>p</em> of <tt class="literal"><span class="pre">a+n</span></tt> such that, for a constant
|
|
object <tt class="literal"><span class="pre">v</span></tt> of type <tt class="literal"><span class="pre">X::value_type</span></tt>, <tt class="literal"><span class="pre">X::reference(a[n]</span>
|
|
<span class="pre">=</span> <span class="pre">v)</span></tt> is equivalent to <tt class="literal"><span class="pre">p</span> <span class="pre">=</span> <span class="pre">v</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>to:</p>
|
|
<blockquote>
|
|
<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">Returns:</th><td class="field-body">an object convertible to <tt class="literal"><span class="pre">value_type</span></tt>. For
|
|
constant objects <tt class="literal"><span class="pre">v</span></tt> of type <tt class="literal"><span class="pre">value_type</span></tt>, and <tt class="literal"><span class="pre">n</span></tt> of
|
|
type <tt class="literal"><span class="pre">difference_type</span></tt>, <tt class="literal"><span class="pre">(*this)[n]</span> <span class="pre">=</span> <span class="pre">v</span></tt> is equivalent
|
|
to <tt class="literal"><span class="pre">*(*this</span> <span class="pre">+</span> <span class="pre">n)</span> <span class="pre">=</span> <span class="pre">v</span></tt>, and <tt class="literal"><span class="pre">static_cast<value_type</span>
|
|
<span class="pre">const&>((*this)[n])</span></tt> is equivalent to
|
|
<tt class="literal"><span class="pre">static_cast<value_type</span> <span class="pre">const&>(*(*this</span> <span class="pre">+</span> <span class="pre">n))</span></tt></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
</blockquote>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="iterator-facade-redundant-clause">
|
|
<h2><a class="toc-backref" href="#id28" name="iterator-facade-redundant-clause">9.27 Iterator_facade: redundant clause</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><tt class="literal"><span class="pre">operator-</span></tt> has both an effects clause and a returns
|
|
clause. Looks like the returns clause should be removed.</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">Remove the returns clause.</p>
|
|
<p>In [lib.iterator.facade] operations:</p>
|
|
<dl class="last">
|
|
<dt>Remove:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">static_cast<Derived</span> <span class="pre">const*>(this)->advance(-n);</span></tt></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
</dl>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="indirect-iterator-incorrect-specification-of-default-constructor">
|
|
<h2><a class="toc-backref" href="#id29" name="indirect-iterator-incorrect-specification-of-default-constructor">9.28 indirect_iterator: incorrect specification of default constructor</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>The default constructor returns "An instance of indirect_iterator
|
|
with a default constructed base object", but the constructor that
|
|
takes an Iterator object returns "An instance of indirect_iterator
|
|
with the iterator_adaptor subobject copy constructed from x." The
|
|
latter is the correct form, since it does not reach inside the base
|
|
class for its semantics. So the default constructor shoudl return
|
|
"An instance of indirect_iterator with a default-constructed
|
|
iterator_adaptor subobject."</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><dl class="first last">
|
|
<dt>Change:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">indirect_iterator</span></tt> with
|
|
a default constructed base object.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>to:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">indirect_iterator</span></tt> with
|
|
a default-constructed <tt class="literal"><span class="pre">m_iterator</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
</dl>
|
|
</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Rationale:</th><td class="field-body">Inheritance from iterator_adaptor has been removed, so we instead
|
|
give the semantics in terms of the (exposition only) member
|
|
<tt class="literal"><span class="pre">m_iterator</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="indirect-iterator-unclear-specification-of-template-constructor">
|
|
<h2><a class="toc-backref" href="#id30" name="indirect-iterator-unclear-specification-of-template-constructor">9.29 indirect_iterator: unclear specification of template constructor</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>The templated constructor that takes an indirect_iterator with a
|
|
different set of template arguments says that it returns "An
|
|
instance of indirect_iterator that is a copy of [the argument]".
|
|
But the type of the argument is different from the type of the
|
|
object being constructed, and there is no description of what
|
|
a "copy" means. The Iterator template parameter for the argument
|
|
must be convertible to the Iterator template parameter for the type
|
|
being constructed, which suggests that the argument's contained
|
|
Iterator object should be converted to the target type's Iterator
|
|
type. Is that what's meant here?
|
|
(Pete later writes: In fact, this problem is present in all of the
|
|
specialized adaptors that have a constructor like this: the
|
|
constructor returns "a copy" of the argument without saying what a
|
|
copy is.)</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><dl class="first last">
|
|
<dt>Change:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">indirect_iterator</span></tt> that is a copy of <tt class="literal"><span class="pre">y</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>to:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">indirect_iterator</span></tt> whose
|
|
<tt class="literal"><span class="pre">m_iterator</span></tt> subobject is constructed from <tt class="literal"><span class="pre">y.base()</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
</dl>
|
|
</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Rationale:</th><td class="field-body">Inheritance from iterator_adaptor has been removed, so we
|
|
instead give the semantics in terms of the member <tt class="literal"><span class="pre">m_iterator</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="transform-iterator-argument-irregularity">
|
|
<h2><a class="toc-backref" href="#id31" name="transform-iterator-argument-irregularity">9.30 transform_iterator argument irregularity</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>The specialized adaptors that take both a Value and a Reference
|
|
template argument all take them in that order, i.e. Value precedes
|
|
Reference in the template argument list, with the exception of
|
|
transform_iterator, where Reference precedes Value. This seems like
|
|
a possible source of confusion. Is there a reason why this order is
|
|
preferable?</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body">NAD</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Rationale:</th><td class="field-body">defaults for Value depend on Reference. A sensible
|
|
Value can almost always be computed from Reference. The first
|
|
parameter is UnaryFunction, so the argument order is already
|
|
different from the other adapters.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="function-output-iterator-overconstrained">
|
|
<h2><a class="toc-backref" href="#id32" name="function-output-iterator-overconstrained">9.31 function_output_iterator overconstrained</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>function_output_iterator requirements says: "The UnaryFunction must
|
|
be Assignable, Copy Constructible, and the expression f(x) must be
|
|
valid, where f is an object of type UnaryFunction and x is an
|
|
object of a type accepted by f."</p>
|
|
<p>Everything starting with "and," somewhat reworded, is actually a
|
|
constraint on output_proxy::operator=. All that's needed to create
|
|
a function_output_iterator object is that the UnaryFunction type be
|
|
Assignable and CopyConstructible. That's also sufficient to
|
|
dereference and to increment such an object. It's only when you try
|
|
to assign through a dereferenced iterator that f(x) has to work,
|
|
and then only for the particular function object that the iterator
|
|
holds and for the particular value that is being assigned.</p>
|
|
<dl>
|
|
<dt>Addition from Jeremy:</dt>
|
|
<dd>The constructor for <tt class="literal"><span class="pre">function_output_iterator</span></tt> is also
|
|
slightly overconstrained because it requires
|
|
the <tt class="literal"><span class="pre">UnaryFunction</span></tt> to have a default constructor
|
|
even when the default constructor of <tt class="literal"><span class="pre">function_output_iterator</span></tt>
|
|
is not used.</dd>
|
|
</dl>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><dl class="first">
|
|
<dt>Change:</dt>
|
|
<dd><tt class="literal"><span class="pre">output_proxy</span> <span class="pre">operator*();</span></tt></dd>
|
|
<dt>to:</dt>
|
|
<dd><tt class="literal"><span class="pre">/*</span> <span class="pre">see</span> <span class="pre">below</span> <span class="pre">*/</span> <span class="pre">operator*();</span></tt></dd>
|
|
</dl>
|
|
<p>After <tt class="literal"><span class="pre">function_output_iterator&</span> <span class="pre">operator++(int);</span></tt> add:</p>
|
|
<pre class="literal-block">
|
|
private:
|
|
UnaryFunction m_f; // exposition only
|
|
</pre>
|
|
<dl>
|
|
<dt>Change:</dt>
|
|
<dd>The <tt class="literal"><span class="pre">UnaryFunction</span></tt> must be Assignable, Copy Constructible,
|
|
and the expression <tt class="literal"><span class="pre">f(x)</span></tt> must be valid, where <tt class="literal"><span class="pre">f</span></tt> is an
|
|
object of type <tt class="literal"><span class="pre">UnaryFunction</span></tt> and <tt class="literal"><span class="pre">x</span></tt> is an object of a
|
|
type accepted by <tt class="literal"><span class="pre">f</span></tt>. The resulting
|
|
<tt class="literal"><span class="pre">function_output_iterator</span></tt> is a model of the Writable and
|
|
Incrementable Iterator concepts.</dd>
|
|
<dt>to:</dt>
|
|
<dd><tt class="literal"><span class="pre">UnaryFunction</span></tt> must be Assignable and Copy Constructible.</dd>
|
|
</dl>
|
|
<p class="last">After the requirements section, add:</p>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<div class="topic">
|
|
<p class="topic-title first"><tt class="literal"><span class="pre">function_output_iterator</span></tt> models</p>
|
|
<blockquote>
|
|
<tt class="literal"><span class="pre">function_output_iterator</span></tt> is a model of the Writable and
|
|
Incrementable Iterator concepts.</blockquote>
|
|
<dl>
|
|
<dt>Change:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">function_output_iterator</span></tt> with
|
|
<tt class="literal"><span class="pre">f</span></tt> stored as a data member.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>to:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Constructs an instance of <tt class="literal"><span class="pre">function_output_iterator</span></tt>
|
|
with <tt class="literal"><span class="pre">m_f</span></tt> constructed from <tt class="literal"><span class="pre">f</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>Change:</dt>
|
|
<dd><p class="first"><tt class="literal"><span class="pre">output_proxy</span> <span class="pre">operator*();</span></tt></p>
|
|
<table class="last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">output_proxy</span></tt> constructed with
|
|
a copy of the unary function <tt class="literal"><span class="pre">f</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>to:</dt>
|
|
<dd><p class="first"><tt class="literal"><span class="pre">operator*();</span></tt></p>
|
|
<table class="last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An object <tt class="literal"><span class="pre">r</span></tt> of unspecified type such that <tt class="literal"><span class="pre">r</span> <span class="pre">=</span> <span class="pre">t</span></tt>
|
|
is equivalent to <tt class="literal"><span class="pre">m_f(t)</span></tt> for all <tt class="literal"><span class="pre">t</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>Remove:</dt>
|
|
<dd><p class="first"><tt class="literal"><span class="pre">function_output_iterator::output_proxy</span></tt> operations</p>
|
|
<p><tt class="literal"><span class="pre">output_proxy(UnaryFunction&</span> <span class="pre">f);</span></tt></p>
|
|
<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">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">output_proxy</span></tt> with <tt class="literal"><span class="pre">f</span></tt> stored as
|
|
a data member.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><tt class="literal"><span class="pre">template</span> <span class="pre"><class</span> <span class="pre">T></span> <span class="pre">output_proxy&</span> <span class="pre">operator=(const</span> <span class="pre">T&</span> <span class="pre">value);</span></tt></p>
|
|
<table class="last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Effects:</th><td class="field-body"><pre class="first last literal-block">
|
|
m_f(value);
|
|
return *this;
|
|
</pre>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
</dl>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
explicit function_output_iterator(const UnaryFunction& f = UnaryFunction());
|
|
</pre>
|
|
<p>to:</p>
|
|
<pre class="literal-block">
|
|
explicit function_output_iterator();
|
|
|
|
explicit function_output_iterator(const UnaryFunction& f);
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
<div class="section" id="should-output-proxy-really-be-a-named-type">
|
|
<h2><a class="toc-backref" href="#id33" name="should-output-proxy-really-be-a-named-type">9.32 Should output_proxy really be a named type?</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>This means someone can store an output_proxy object for later use,
|
|
whatever that means. It also constrains output_proxy to hold a copy
|
|
of the function object, rather than a pointer to the iterator
|
|
object. Is all this mechanism really necessary?</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body">See issue 9.31.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="istreambuf-iterator-isn-t-a-readable-iterator">
|
|
<h2><a class="toc-backref" href="#id34" name="istreambuf-iterator-isn-t-a-readable-iterator">9.33 istreambuf_iterator isn't a Readable Iterator</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>c++std-lib-12333:</p>
|
|
<blockquote>
|
|
N1550 requires that for a Readable Iterator a of type X, <tt class="literal"><span class="pre">*a</span></tt>
|
|
returns an object of type
|
|
<tt class="literal"><span class="pre">iterator_traits<X>::reference</span></tt>. <tt class="literal"><span class="pre">istreambuf_iterator::operator*</span></tt>
|
|
returns <tt class="literal"><span class="pre">charT</span></tt>, but <tt class="literal"><span class="pre">istreambuf_iterator::reference</span></tt> is
|
|
<tt class="literal"><span class="pre">charT&</span></tt>. So am I overlooking something, or is
|
|
<tt class="literal"><span class="pre">istreambuf_iterator</span></tt> not Readable.</blockquote>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">Remove all constraints on
|
|
<tt class="literal"><span class="pre">iterator_traits<X>::reference</span></tt> in Readable Iterator and Lvalue
|
|
Iterator. Change Lvalue Iterator to refer to <tt class="literal"><span class="pre">T&</span></tt> instead of
|
|
<tt class="literal"><span class="pre">iterator_traits<X>::reference</span></tt>.</p>
|
|
<dl>
|
|
<dt>Change:</dt>
|
|
<dd>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Readable Iterator</em>
|
|
concept for the value type <tt class="literal"><span class="pre">T</span></tt> if the following expressions
|
|
are valid and respect the stated semantics. <tt class="literal"><span class="pre">U</span></tt> is the type
|
|
of any specified member of type <tt class="literal"><span class="pre">T</span></tt>.</dd>
|
|
<dt>to:</dt>
|
|
<dd>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Readable Iterator</em>
|
|
concept for value type <tt class="literal"><span class="pre">T</span></tt> if, in addition to <tt class="literal"><span class="pre">X</span></tt> being
|
|
Assignable and Copy Constructible, the following expressions
|
|
are valid and respect the stated semantics. <tt class="literal"><span class="pre">U</span></tt> is the type
|
|
of any specified member of type <tt class="literal"><span class="pre">T</span></tt>.</dd>
|
|
</dl>
|
|
<p>From the Input Iterator Requirements table, remove:</p>
|
|
<blockquote>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="37%" />
|
|
<col width="37%" />
|
|
<col width="26%" />
|
|
</colgroup>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">iterator_traits<X>::reference</span></tt></td>
|
|
<td>Convertible to
|
|
<tt class="literal"><span class="pre">iterator_traits<X>::value_type</span></tt></td>
|
|
<td> </td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>Change:</p>
|
|
<blockquote>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="37%" />
|
|
<col width="37%" />
|
|
<col width="26%" />
|
|
</colgroup>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">*a</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">iterator_traits<X>::reference</span></tt></td>
|
|
<td>pre: <tt class="literal"><span class="pre">a</span></tt> is
|
|
dereferenceable. If <tt class="literal"><span class="pre">a</span>
|
|
<span class="pre">==</span> <span class="pre">b</span></tt> then <tt class="literal"><span class="pre">*a</span></tt> is
|
|
equivalent to <tt class="literal"><span class="pre">*b</span></tt></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>to:</p>
|
|
<blockquote>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="28%" />
|
|
<col width="20%" />
|
|
<col width="52%" />
|
|
</colgroup>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">*a</span></tt></td>
|
|
<td>Convertible to <tt class="literal"><span class="pre">T</span></tt></td>
|
|
<td><dl class="first last">
|
|
<dt>pre: <tt class="literal"><span class="pre">a</span></tt> is dereferenceable. If <tt class="literal"><span class="pre">a</span> <span class="pre">==</span> <span class="pre">b</span></tt> then <tt class="literal"><span class="pre">*a</span></tt></dt>
|
|
<dd>is equivalent to <tt class="literal"><span class="pre">*b</span></tt>.</dd>
|
|
</dl>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<dl>
|
|
<dt>Change:</dt>
|
|
<dd>The <em>Lvalue Iterator</em> concept adds the requirement that the
|
|
<tt class="literal"><span class="pre">reference</span></tt> type be a reference to the value type of the
|
|
iterator.</dd>
|
|
<dt>to:</dt>
|
|
<dd>The <em>Lvalue Iterator</em> concept adds the requirement that the
|
|
return type of <tt class="literal"><span class="pre">operator*</span></tt> type be a reference to the value
|
|
type of the iterator.</dd>
|
|
</dl>
|
|
<p>Change:</p>
|
|
<blockquote>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="42%" />
|
|
<col width="14%" />
|
|
<col width="44%" />
|
|
</colgroup>
|
|
<thead valign="bottom">
|
|
<tr><th colspan="3">Lvalue Iterator Requirements</th>
|
|
</tr>
|
|
<tr><th>Expression</th>
|
|
<th>Return Type</th>
|
|
<th>Assertion</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">iterator_traits<X>::reference</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">T&</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">T</span></tt> is <em>cv</em>
|
|
<tt class="literal"><span class="pre">iterator_traits<X>::value_type</span></tt>
|
|
where <em>cv</em> is an optional
|
|
cv-qualification</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>to:</p>
|
|
<blockquote>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="22%" />
|
|
<col width="19%" />
|
|
<col width="59%" />
|
|
</colgroup>
|
|
<thead valign="bottom">
|
|
<tr><th colspan="3">Lvalue Iterator Requirements</th>
|
|
</tr>
|
|
<tr><th>Expression</th>
|
|
<th>Return Type</th>
|
|
<th>Note/Assertion</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">*a</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">T&</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">T</span></tt> is <em>cv</em>
|
|
<tt class="literal"><span class="pre">iterator_traits<X>::value_type</span></tt>
|
|
where <em>cv</em> is an optional
|
|
cv-qualification.
|
|
pre: <tt class="literal"><span class="pre">a</span></tt> is
|
|
dereferenceable. If <tt class="literal"><span class="pre">a</span>
|
|
<span class="pre">==</span> <span class="pre">b</span></tt> then <tt class="literal"><span class="pre">*a</span></tt> is
|
|
equivalent to <tt class="literal"><span class="pre">*b</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p class="last">At the end of the section reverse_iterator models, add:
|
|
The type <tt class="literal"><span class="pre">iterator_traits<Iterator>::reference</span></tt> must be the type of
|
|
<tt class="literal"><span class="pre">*i</span></tt>, where <tt class="literal"><span class="pre">i</span></tt> is an object of type <tt class="literal"><span class="pre">Iterator</span></tt>.</p>
|
|
</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Rationale:</th><td class="field-body"><p class="first">Ideally there should be requirements on the reference
|
|
type, however, since Readable Iterator is suppose to correspond
|
|
to the current standard iterator requirements (which do not place
|
|
requirements on the reference type) we will leave them off for
|
|
now. There is a DR in process with respect to the reference type
|
|
in the stadard iterator requirements. Once that is resolved we
|
|
will revisit this issue for Readable Iterator and Lvalue
|
|
Iterator.</p>
|
|
<p class="last">We added Assignable to the requirements for Readable
|
|
Iterator. This is needed to have Readable Iterator coincide with
|
|
the capabilities of Input Iterator.</p>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="iterator-facade-free-functions-unspecified">
|
|
<h2><a class="toc-backref" href="#id35" name="iterator-facade-free-functions-unspecified">9.34 iterator_facade free functions unspecified</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>c++std-lib-12562:</p>
|
|
<blockquote>
|
|
The template functions <tt class="literal"><span class="pre">operator==</span></tt>, <tt class="literal"><span class="pre">operator!=</span></tt>,
|
|
<tt class="literal"><span class="pre">operator<</span></tt>, <tt class="literal"><span class="pre">operator<=</span></tt>, <tt class="literal"><span class="pre">operator></span></tt>, <tt class="literal"><span class="pre">operator>=</span></tt>, and
|
|
<tt class="literal"><span class="pre">operator-</span></tt> that take two arguments that are specializations of
|
|
iterator_facade have no specification. The template function
|
|
operator+ that takes an argument that is a specialization of
|
|
iterator_facade and an argument of type difference_type has no
|
|
specification.</blockquote>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">Add the missing specifications.</p>
|
|
<pre class="literal-block">
|
|
template <class Dr, class V, class TC, class R, class D>
|
|
Derived operator+ (iterator_facade<Dr,V,TC,R,D> const&,
|
|
typename Derived::difference_type n);
|
|
|
|
template <class Dr, class V, class TC, class R, class D>
|
|
Derived operator+ (typename Derived::difference_type n,
|
|
iterator_facade<Dr,V,TC,R,D> const&);
|
|
</pre>
|
|
<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">Effects:</th><td class="field-body"><pre class="first last literal-block">
|
|
Derived tmp(static_cast<Derived const*>(this));
|
|
return tmp += n;
|
|
</pre>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<pre class="literal-block">
|
|
template <class Dr1, class V1, class TC1, class R1, class D1,
|
|
class Dr2, class V2, class TC2, class R2, class D2>
|
|
typename enable_if_interoperable<Dr1,Dr2,bool>::type
|
|
operator ==(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
|
|
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
|
</pre>
|
|
<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">Returns:</th><td class="field-body">if <tt class="literal"><span class="pre">is_convertible<Dr2,Dr1>::value</span></tt>, then
|
|
<tt class="literal"><span class="pre">lhs.equal(rhs)</span></tt>. Otherwise, <tt class="literal"><span class="pre">rhs.equal(lhs)</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<pre class="literal-block">
|
|
template <class Dr1, class V1, class TC1, class R1, class D1,
|
|
class Dr2, class V2, class TC2, class R2, class D2>
|
|
typename enable_if_interoperable<Dr1,Dr2,bool>::type
|
|
operator !=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
|
|
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
|
</pre>
|
|
<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">Returns:</th><td class="field-body">if <tt class="literal"><span class="pre">is_convertible<Dr2,Dr1>::value</span></tt>, then
|
|
<tt class="literal"><span class="pre">!lhs.equal(rhs)</span></tt>. Otherwise, <tt class="literal"><span class="pre">!rhs.equal(lhs)</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<pre class="literal-block">
|
|
template <class Dr1, class V1, class TC1, class R1, class D1,
|
|
class Dr2, class V2, class TC2, class R2, class D2>
|
|
typename enable_if_interoperable<Dr1,Dr2,bool>::type
|
|
operator <(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
|
|
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
|
</pre>
|
|
<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">Returns:</th><td class="field-body">if <tt class="literal"><span class="pre">is_convertible<Dr2,Dr1>::value</span></tt>, then
|
|
<tt class="literal"><span class="pre">lhs.distance_to(rhs)</span> <span class="pre"><</span> <span class="pre">0</span></tt>. Otherwise, <tt class="literal"><span class="pre">rhs.distance_to(lhs)</span> <span class="pre">></span>
|
|
<span class="pre">0</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<pre class="literal-block">
|
|
template <class Dr1, class V1, class TC1, class R1, class D1,
|
|
class Dr2, class V2, class TC2, class R2, class D2>
|
|
typename enable_if_interoperable<Dr1,Dr2,bool>::type
|
|
operator <=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
|
|
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
|
</pre>
|
|
<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">Returns:</th><td class="field-body">if <tt class="literal"><span class="pre">is_convertible<Dr2,Dr1>::value</span></tt>, then
|
|
<tt class="literal"><span class="pre">lhs.distance_to(rhs)</span> <span class="pre"><=</span> <span class="pre">0</span></tt>. Otherwise, <tt class="literal"><span class="pre">rhs.distance_to(lhs)</span>
|
|
<span class="pre">>=</span> <span class="pre">0</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<pre class="literal-block">
|
|
template <class Dr1, class V1, class TC1, class R1, class D1,
|
|
class Dr2, class V2, class TC2, class R2, class D2>
|
|
typename enable_if_interoperable<Dr1,Dr2,bool>::type
|
|
operator >(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
|
|
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
|
</pre>
|
|
<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">Returns:</th><td class="field-body">if <tt class="literal"><span class="pre">is_convertible<Dr2,Dr1>::value</span></tt>, then
|
|
<tt class="literal"><span class="pre">lhs.distance_to(rhs)</span> <span class="pre">></span> <span class="pre">0</span></tt>. Otherwise,
|
|
<tt class="literal"><span class="pre">rhs.distance_to(lhs)</span> <span class="pre"><</span> <span class="pre">0</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<pre class="literal-block">
|
|
template <class Dr1, class V1, class TC1, class R1, class D1,
|
|
class Dr2, class V2, class TC2, class R2, class D2>
|
|
typename enable_if_interoperable<Dr1,Dr2,bool>::type
|
|
operator >=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
|
|
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
|
</pre>
|
|
<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">Returns:</th><td class="field-body">if <tt class="literal"><span class="pre">is_convertible<Dr2,Dr1>::value</span></tt>, then
|
|
<tt class="literal"><span class="pre">lhs.distance_to(rhs)</span> <span class="pre">>=</span> <span class="pre">0</span></tt>. Otherwise,
|
|
<tt class="literal"><span class="pre">rhs.distance_to(lhs)</span> <span class="pre"><=</span> <span class="pre">0</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<pre class="literal-block">
|
|
template <class Dr1, class V1, class TC1, class R1, class D1,
|
|
class Dr2, class V2, class TC2, class R2, class D2>
|
|
typename enable_if_interoperable<Dr1,Dr2,difference>::type
|
|
operator -(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
|
|
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
|
</pre>
|
|
<table class="last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Return Type:</th><td class="field-body">if <tt class="literal"><span class="pre">is_convertible<Dr2,Dr1>::value</span></tt>, then
|
|
<tt class="literal"><span class="pre">difference</span></tt> shall be
|
|
<tt class="literal"><span class="pre">iterator_traits<Dr1>::difference_type</span></tt>. Otherwise,
|
|
<tt class="literal"><span class="pre">difference</span></tt> shall be
|
|
<tt class="literal"><span class="pre">iterator_traits<Dr2>::difference_type</span></tt>.</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">if <tt class="literal"><span class="pre">is_convertible<Dr2,Dr1>::value</span></tt>, then
|
|
<tt class="literal"><span class="pre">-lhs.distance_to(rhs)</span></tt>. Otherwise,
|
|
<tt class="literal"><span class="pre">rhs.distance_to(lhs)</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="iterator-facade-too-many-equals">
|
|
<h2><a class="toc-backref" href="#id36" name="iterator-facade-too-many-equals">9.35 iterator_facade: too many equals?</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>c++std-lib-12563:</p>
|
|
<blockquote>
|
|
<p>The table listing the functions required for types derived from
|
|
iterator_facade has two functions named equal and two named
|
|
distance_to:</p>
|
|
<pre class="literal-block">
|
|
c.equal(b)
|
|
c.equal(y)
|
|
c.distance_to(b)
|
|
c.distance_to(z)
|
|
</pre>
|
|
<p>where b and c are const objects of the derived type, y and z are
|
|
constant objects of certain iterator types that are interoperable
|
|
with the derived type. Seems like the 'b' versions are
|
|
redundant: in both cases, the other version will take a 'b'. In
|
|
fact, iterator_adaptor is specified to use iterator_facade, but
|
|
does not provide the 'b' versions of these functions.</p>
|
|
<p>Are the 'b' versions needed?</p>
|
|
</blockquote>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">Remove the 'b' versions.</p>
|
|
<p>In <tt class="literal"><span class="pre">iterator_facade</span></tt> requirements, remove:</p>
|
|
<blockquote>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="19%" />
|
|
<col width="18%" />
|
|
<col width="36%" />
|
|
<col width="26%" />
|
|
</colgroup>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">c.equal(b)</span></tt></td>
|
|
<td>convertible to bool</td>
|
|
<td>true iff <tt class="literal"><span class="pre">b</span></tt> and <tt class="literal"><span class="pre">c</span></tt> are
|
|
equivalent.</td>
|
|
<td>Single Pass Iterator</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>and remove:</p>
|
|
<blockquote class="last">
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="19%" />
|
|
<col width="18%" />
|
|
<col width="36%" />
|
|
<col width="26%" />
|
|
</colgroup>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">c.distance_to(b)</span></tt></td>
|
|
<td>convertible to
|
|
X::difference_type</td>
|
|
<td>equivalent to <tt class="literal"><span class="pre">distance(c,</span> <span class="pre">b)</span></tt></td>
|
|
<td>Random Access Traversal
|
|
Iterator</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="iterator-facade-function-requirements">
|
|
<h2><a class="toc-backref" href="#id37" name="iterator-facade-function-requirements">9.36 iterator_facade function requirements</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>c++std-lib-12636:</p>
|
|
<blockquote>
|
|
<p>The table that lists required functions for the derived type X
|
|
passed to iterator_facade lists, among others:</p>
|
|
<p>for a single pass iterator:</p>
|
|
<pre class="literal-block">
|
|
c.equal(b)
|
|
c.equal(y)
|
|
</pre>
|
|
<p>where b and c are const X objects, and y is a const object of a
|
|
single pass iterator that is interoperable with X. Since X is
|
|
interoperable with itself, c.equal(b) is redundant. There is a
|
|
difference in their descriptions, but its meaning isn't
|
|
clear. The first is "true iff b and c are equivalent", and the
|
|
second is "true iff c and y refer to the same position." Is there
|
|
a difference between the undefined term "equivalent" and "refer
|
|
to the same position"?</p>
|
|
<p>Similarly, for a random access traversal iterator:</p>
|
|
<pre class="literal-block">
|
|
c.distance_to(b)
|
|
c.distance_to(z)
|
|
</pre>
|
|
<p>where z is a constant object of a random access traversal
|
|
iterator that is interoperable with X. Again, X is interoperable
|
|
with itself, so c.distance_to(b) is redundant. Also, the
|
|
specification for c.distance_to(z) isn't valid. It's written
|
|
as "equivalent to distance(c, z)". The template function distance
|
|
takes two arguments of the same type, so distance(c, z) isn't
|
|
valid if c and z are different types. Should it be
|
|
distance(c, (X)z)?</p>
|
|
</blockquote>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">Removed the 'b' versions (see 9.35) and added the cast.</p>
|
|
<p>Change:</p>
|
|
<blockquote>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="19%" />
|
|
<col width="18%" />
|
|
<col width="36%" />
|
|
<col width="26%" />
|
|
</colgroup>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">c.distance_to(z)</span></tt></td>
|
|
<td>convertible to
|
|
X::difference_type</td>
|
|
<td>equivalent to <tt class="literal"><span class="pre">distance(c,</span> <span class="pre">z)</span></tt>.
|
|
Implements <tt class="literal"><span class="pre">c</span> <span class="pre">-</span> <span class="pre">z</span></tt>, <tt class="literal"><span class="pre">c</span> <span class="pre"><</span> <span class="pre">z</span></tt>, <tt class="literal"><span class="pre">c</span>
|
|
<span class="pre"><=</span> <span class="pre">z</span></tt>, <tt class="literal"><span class="pre">c</span> <span class="pre">></span> <span class="pre">z</span></tt>, and <tt class="literal"><span class="pre">c</span> <span class="pre">>=</span> <span class="pre">c</span></tt>.</td>
|
|
<td>Random Access Traversal
|
|
Iterator</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>to:</p>
|
|
<blockquote class="last">
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="21%" />
|
|
<col width="23%" />
|
|
<col width="27%" />
|
|
<col width="29%" />
|
|
</colgroup>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">c.distance_to(z)</span></tt></td>
|
|
<td>convertible to
|
|
<tt class="literal"><span class="pre">F::difference_type</span></tt></td>
|
|
<td>equivalent to
|
|
<tt class="literal"><span class="pre">distance(c,</span> <span class="pre">X(z))</span></tt>.</td>
|
|
<td>Random Access Traversal
|
|
Iterator</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="section" id="more-issues-not-from-matt-s-list">
|
|
<h1><a class="toc-backref" href="#id38" name="more-issues-not-from-matt-s-list">More Issues (not from Matt's list)</a></h1>
|
|
<div class="section" id="x-inheritance-in-iterator-adaptor-and-other-adaptors-is-an-overspecification">
|
|
<h2><a class="toc-backref" href="#id39" name="x-inheritance-in-iterator-adaptor-and-other-adaptors-is-an-overspecification">9.37x Inheritance in iterator_adaptor and other adaptors is an overspecification</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>c++std-lib-12696:
|
|
The paper requires that iterator_adaptor be derived from an
|
|
appropriate instance of iterator_facade, and that most of the specific
|
|
forms of adaptors be derived from appropriate instances of
|
|
iterator_adaptor. That seems like overspecification, and we ought to
|
|
look at specifying these things in terms of what the various templates
|
|
provide rather than how they're implemented.</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">Remove the specfication of inheritance, and add explicit
|
|
specification of all the functionality that was inherited from the
|
|
specialized iterators.</p>
|
|
<p>In iterator_adaptor, inheritance is retained, sorry NAD. Also,
|
|
the Interoperable Iterators concept is added to the new iterator
|
|
concepts, and this concept is used in the specification of the
|
|
iterator adaptors.</p>
|
|
<p>In n1550, after [lib.random.access.traversal.iterators], add:</p>
|
|
<blockquote>
|
|
<p>Interoperable Iterators [lib.interoperable.iterators]</p>
|
|
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> that models Single Pass Iterator
|
|
is <em>interoperable with</em> a class or built-in type <tt class="literal"><span class="pre">Y</span></tt> that
|
|
also models Single Pass Iterator if the following expressions
|
|
are valid and respect the stated semantics. In the tables
|
|
below, <tt class="literal"><span class="pre">x</span></tt> is an object of type <tt class="literal"><span class="pre">X</span></tt>, <tt class="literal"><span class="pre">y</span></tt> is an object of
|
|
type <tt class="literal"><span class="pre">Y</span></tt>, <tt class="literal"><span class="pre">Distance</span></tt> is
|
|
<tt class="literal"><span class="pre">iterator_traits<Y>::difference_type</span></tt>, and <tt class="literal"><span class="pre">n</span></tt> represents a
|
|
constant object of type <tt class="literal"><span class="pre">Distance</span></tt>.</p>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="13%" />
|
|
<col width="27%" />
|
|
<col width="60%" />
|
|
</colgroup>
|
|
<thead valign="bottom">
|
|
<tr><th>Expression</th>
|
|
<th>Return Type</th>
|
|
<th>Assertion/Precondition/Postcondition</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">y</span> <span class="pre">=</span> <span class="pre">x</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">Y</span></tt></td>
|
|
<td>post: <tt class="literal"><span class="pre">y</span> <span class="pre">==</span> <span class="pre">x</span></tt></td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">Y(x)</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">Y</span></tt></td>
|
|
<td>post: <tt class="literal"><span class="pre">Y(x)</span> <span class="pre">==</span> <span class="pre">x</span></tt></td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">x</span> <span class="pre">==</span> <span class="pre">y</span></tt></td>
|
|
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">==</span></tt> is an equivalence relation over its domain.</td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">y</span> <span class="pre">==</span> <span class="pre">x</span></tt></td>
|
|
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">==</span></tt> is an equivalence relation over its domain.</td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">x</span> <span class="pre">!=</span> <span class="pre">y</span></tt></td>
|
|
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">bool(a==b)</span> <span class="pre">!=</span> <span class="pre">bool(a!=b)</span></tt> over its domain.</td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">y</span> <span class="pre">!=</span> <span class="pre">x</span></tt></td>
|
|
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">bool(a==b)</span> <span class="pre">!=</span> <span class="pre">bool(a!=b)</span></tt> over its domain.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>If <tt class="literal"><span class="pre">X</span></tt> and <tt class="literal"><span class="pre">Y</span></tt> both model Random Access Traversal Iterator then
|
|
the following additional requirements must be met.</p>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="12%" />
|
|
<col width="25%" />
|
|
<col width="23%" />
|
|
<col width="41%" />
|
|
</colgroup>
|
|
<thead valign="bottom">
|
|
<tr><th>Expression</th>
|
|
<th>Return Type</th>
|
|
<th>Operational Semantics</th>
|
|
<th>Assertion/ Precondition</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">x</span> <span class="pre"><</span> <span class="pre">y</span></tt></td>
|
|
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">y</span> <span class="pre">-</span> <span class="pre">x</span> <span class="pre">></span> <span class="pre">0</span></tt></td>
|
|
<td><tt class="literal"><span class="pre"><</span></tt> is a total ordering relation</td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">y</span> <span class="pre"><</span> <span class="pre">x</span></tt></td>
|
|
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">x</span> <span class="pre">-</span> <span class="pre">y</span> <span class="pre">></span> <span class="pre">0</span></tt></td>
|
|
<td><tt class="literal"><span class="pre"><</span></tt> is a total ordering relation</td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">x</span> <span class="pre">></span> <span class="pre">y</span></tt></td>
|
|
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">y</span> <span class="pre"><</span> <span class="pre">x</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">></span></tt> is a total ordering relation</td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">y</span> <span class="pre">></span> <span class="pre">x</span></tt></td>
|
|
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">x</span> <span class="pre"><</span> <span class="pre">y</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">></span></tt> is a total ordering relation</td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">x</span> <span class="pre">>=</span> <span class="pre">y</span></tt></td>
|
|
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">!(x</span> <span class="pre"><</span> <span class="pre">y)</span></tt></td>
|
|
<td> </td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">y</span> <span class="pre">>=</span> <span class="pre">x</span></tt></td>
|
|
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">!(y</span> <span class="pre"><</span> <span class="pre">x)</span></tt></td>
|
|
<td> </td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">x</span> <span class="pre"><=</span> <span class="pre">y</span></tt></td>
|
|
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">!(x</span> <span class="pre">></span> <span class="pre">y)</span></tt></td>
|
|
<td> </td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">y</span> <span class="pre"><=</span> <span class="pre">x</span></tt></td>
|
|
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">!(y</span> <span class="pre">></span> <span class="pre">x)</span></tt></td>
|
|
<td> </td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">y</span> <span class="pre">-</span> <span class="pre">x</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">Distance</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">distance(Y(x),y)</span></tt></td>
|
|
<td>pre: there exists a value <tt class="literal"><span class="pre">n</span></tt> of
|
|
<tt class="literal"><span class="pre">Distance</span></tt> such that <tt class="literal"><span class="pre">x</span> <span class="pre">+</span> <span class="pre">n</span> <span class="pre">==</span> <span class="pre">y</span></tt>.
|
|
<tt class="literal"><span class="pre">y</span> <span class="pre">==</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">(y</span> <span class="pre">-</span> <span class="pre">x)</span></tt>.</td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">x</span> <span class="pre">-</span> <span class="pre">y</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">Distance</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">distance(y,Y(x))</span></tt></td>
|
|
<td>pre: there exists a value <tt class="literal"><span class="pre">n</span></tt> of
|
|
<tt class="literal"><span class="pre">Distance</span></tt> such that <tt class="literal"><span class="pre">y</span> <span class="pre">+</span> <span class="pre">n</span> <span class="pre">==</span> <span class="pre">x</span></tt>.
|
|
<tt class="literal"><span class="pre">x</span> <span class="pre">==</span> <span class="pre">y</span> <span class="pre">+</span> <span class="pre">(x</span> <span class="pre">-</span> <span class="pre">y)</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>In N1530:</p>
|
|
<blockquote class="last">
|
|
<p>In [lib.iterator.adaptor]</p>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
class iterator_adaptor
|
|
: public iterator_facade<Derived, /* see details ...*/>
|
|
</pre>
|
|
<p>To:</p>
|
|
<pre class="literal-block">
|
|
class iterator_adaptor
|
|
: public iterator_facade<Derived, *V'*, *C'*, *R'*, *D'*> // see details
|
|
</pre>
|
|
<dl>
|
|
<dt>Change the text from:</dt>
|
|
<dd>The <tt class="literal"><span class="pre">Base</span></tt> type must implement the expressions involving
|
|
<tt class="literal"><span class="pre">m_iterator</span></tt> in the specifications...</dd>
|
|
<dt>until the end of the <strong>iterator_adaptor requirements</strong> section, to:</dt>
|
|
<dd>The <tt class="literal"><span class="pre">Base</span></tt> argument shall be Assignable and Copy Constructible.</dd>
|
|
</dl>
|
|
<p>Add:</p>
|
|
</blockquote>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<div class="topic">
|
|
<p class="topic-title first"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> base class parameters</p>
|
|
<blockquote>
|
|
<p>The <em>V'</em>, <em>C'</em>, <em>R'</em>, and <em>D'</em> parameters of the <tt class="literal"><span class="pre">iterator_facade</span></tt>
|
|
used as a base class in the summary of <tt class="literal"><span class="pre">iterator_adaptor</span></tt>
|
|
above are defined as follows:</p>
|
|
<pre class="literal-block">
|
|
<em>V'</em> = if (Value is use_default)
|
|
return iterator_traits<Base>::value_type
|
|
else
|
|
return Value
|
|
|
|
<em>C'</em> = if (CategoryOrTraversal is use_default)
|
|
return iterator_traversal<Base>::type
|
|
else
|
|
return CategoryOrTraversal
|
|
|
|
<em>R'</em> = if (Reference is use_default)
|
|
if (Value is use_default)
|
|
return iterator_traits<Base>::reference
|
|
else
|
|
return Value&
|
|
else
|
|
return Reference
|
|
|
|
<em>D'</em> = if (Difference is use_default)
|
|
return iterator_traits<Base>::difference_type
|
|
else
|
|
return Difference
|
|
</pre>
|
|
</blockquote>
|
|
<p>In [lib.iterator.special.adaptors]</p>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
class indirect_iterator
|
|
: public iterator_adaptor</* see discussion */>
|
|
{
|
|
friend class iterator_core_access;
|
|
</pre>
|
|
<p>to:</p>
|
|
<pre class="literal-block">
|
|
class indirect_iterator
|
|
{
|
|
public:
|
|
typedef /* see below */ value_type;
|
|
typedef /* see below */ reference;
|
|
typedef /* see below */ pointer;
|
|
typedef /* see below */ difference_type;
|
|
typedef /* see below */ iterator_category;
|
|
</pre>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
private: // as-if specification
|
|
typename indirect_iterator::reference dereference() const
|
|
{
|
|
return **this->base();
|
|
}
|
|
</pre>
|
|
<p>to:</p>
|
|
<pre class="literal-block">
|
|
Iterator const& base() const;
|
|
reference operator*() const;
|
|
indirect_iterator& operator++();
|
|
indirect_iterator& operator--();
|
|
private:
|
|
Iterator m_iterator; // exposition
|
|
</pre>
|
|
<p>After the synopsis add:</p>
|
|
<blockquote>
|
|
<p>The member types of <tt class="literal"><span class="pre">indirect_iterator</span></tt> are defined
|
|
according to the following pseudo-code, where <tt class="literal"><span class="pre">V</span></tt> is
|
|
<tt class="literal"><span class="pre">iterator_traits<Iterator>::value_type</span></tt></p>
|
|
<pre class="literal-block">
|
|
if (Value is use_default) then
|
|
typedef remove_const<pointee<V>::type>::type value_type;
|
|
else
|
|
typedef remove_const<Value>::type value_type;
|
|
|
|
if (Reference is use_default) then
|
|
if (Value is use_default) then
|
|
typedef indirect_reference<V>::type reference;
|
|
else
|
|
typedef Value& reference;
|
|
else
|
|
typedef Reference reference;
|
|
|
|
if (Value is use_default) then
|
|
typedef pointee<V>::type* pointer;
|
|
else
|
|
typedef Value* pointer;
|
|
|
|
if (Difference is use_default)
|
|
typedef iterator_traits<Iterator>::difference_type difference_type;
|
|
else
|
|
typedef Difference difference_type;
|
|
|
|
if (CategoryOrTraversal is use_default)
|
|
typedef <em>iterator-category</em>(
|
|
iterator_traversal<Iterator>::type,``reference``,``value_type``
|
|
) iterator_category;
|
|
else
|
|
typedef <em>iterator-category</em>(
|
|
CategoryOrTraversal,``reference``,``value_type``
|
|
) iterator_category;
|
|
</pre>
|
|
</blockquote>
|
|
<p>[Note: See resolution to 9.44y for a description of <tt class="literal"><span class="pre">pointee</span></tt> and
|
|
<tt class="literal"><span class="pre">indirect_reference</span></tt>]</p>
|
|
<p>After the requirements section, add:</p>
|
|
</div>
|
|
<div class="topic">
|
|
<p class="topic-title first"><tt class="literal"><span class="pre">indirect_iterator</span></tt> models</p>
|
|
<blockquote>
|
|
<p>In addition to the concepts indicated by <tt class="literal"><span class="pre">iterator_category</span></tt>
|
|
and by <tt class="literal"><span class="pre">iterator_traversal<indirect_iterator>::type</span></tt>, a
|
|
specialization of <tt class="literal"><span class="pre">indirect_iterator</span></tt> models the following
|
|
concepts, Where <tt class="literal"><span class="pre">v</span></tt> is an object of
|
|
<tt class="literal"><span class="pre">iterator_traits<Iterator>::value_type</span></tt>:</p>
|
|
<blockquote>
|
|
<ul class="simple">
|
|
<li>Readable Iterator if <tt class="literal"><span class="pre">reference(*v)</span></tt> is convertible to
|
|
<tt class="literal"><span class="pre">value_type</span></tt>.</li>
|
|
<li>Writable Iterator if <tt class="literal"><span class="pre">reference(*v)</span> <span class="pre">=</span> <span class="pre">t</span></tt> is a valid
|
|
expression (where <tt class="literal"><span class="pre">t</span></tt> is an object of type
|
|
<tt class="literal"><span class="pre">indirect_iterator::value_type</span></tt>)</li>
|
|
<li>Lvalue Iterator if <tt class="literal"><span class="pre">reference</span></tt> is a reference type.</li>
|
|
</ul>
|
|
</blockquote>
|
|
<p><tt class="literal"><span class="pre">indirect_iterator<X,V1,C1,R1,D1></span></tt> is interoperable with
|
|
<tt class="literal"><span class="pre">indirect_iterator<Y,V2,C2,R2,D2></span></tt> if and only if <tt class="literal"><span class="pre">X</span></tt> is
|
|
interoperable with <tt class="literal"><span class="pre">Y</span></tt>.</p>
|
|
</blockquote>
|
|
<p>Before <tt class="literal"><span class="pre">indirect_iterator();</span></tt> add:</p>
|
|
<blockquote>
|
|
In addition to the operations required by the concepts described
|
|
above, specializations of <tt class="literal"><span class="pre">indirect_iterator</span></tt> provide the
|
|
following operations.</blockquote>
|
|
<dl>
|
|
<dt>Change:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">indirect_iterator</span></tt> with
|
|
the <tt class="literal"><span class="pre">iterator_adaptor</span></tt> subobject copy constructed from <tt class="literal"><span class="pre">x</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>to:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">indirect_iterator</span></tt> with
|
|
<tt class="literal"><span class="pre">m_iterator</span></tt> copy constructed from <tt class="literal"><span class="pre">x</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
</dl>
|
|
<p>At the end of the indirect_iterator operations add:</p>
|
|
<blockquote>
|
|
<p><tt class="literal"><span class="pre">Iterator</span> <span class="pre">const&</span> <span class="pre">base()</span> <span class="pre">const;</span></tt></p>
|
|
<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">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">m_iterator</span></tt></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><tt class="literal"><span class="pre">reference</span> <span class="pre">operator*()</span> <span class="pre">const;</span></tt></p>
|
|
<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">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">**m_iterator</span></tt></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><tt class="literal"><span class="pre">indirect_iterator&</span> <span class="pre">operator++();</span></tt></p>
|
|
<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">Effects:</th><td class="field-body"><tt class="literal"><span class="pre">++m_iterator</span></tt></td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">*this</span></tt></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><tt class="literal"><span class="pre">indirect_iterator&</span> <span class="pre">operator--();</span></tt></p>
|
|
<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">Effects:</th><td class="field-body"><tt class="literal"><span class="pre">--m_iterator</span></tt></td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">*this</span></tt></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
template <class Iterator>
|
|
class reverse_iterator :
|
|
public iterator_adaptor< reverse_iterator<Iterator>, Iterator >
|
|
{
|
|
friend class iterator_core_access;
|
|
</pre>
|
|
<p>to:</p>
|
|
<pre class="literal-block">
|
|
template <class Iterator>
|
|
class reverse_iterator
|
|
{
|
|
public:
|
|
typedef iterator_traits<Iterator>::value_type value_type;
|
|
typedef iterator_traits<Iterator>::reference reference;
|
|
typedef iterator_traits<Iterator>::pointer pointer;
|
|
typedef iterator_traits<Iterator>::difference_type difference_type;
|
|
typedef /* see below */ iterator_category;
|
|
</pre>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
private: // as-if specification
|
|
typename reverse_iterator::reference dereference() const { return *prior(this->base()); }
|
|
|
|
void increment() { --this->base_reference(); }
|
|
void decrement() { ++this->base_reference(); }
|
|
|
|
void advance(typename reverse_iterator::difference_type n)
|
|
{
|
|
this->base_reference() += -n;
|
|
}
|
|
|
|
template <class OtherIterator>
|
|
typename reverse_iterator::difference_type
|
|
distance_to(reverse_iterator<OtherIterator> const& y) const
|
|
{
|
|
return this->base_reference() - y.base();
|
|
}
|
|
</pre>
|
|
<p>to:</p>
|
|
<pre class="literal-block">
|
|
Iterator const& base() const;
|
|
reference operator*() const;
|
|
reverse_iterator& operator++();
|
|
reverse_iterator& operator--();
|
|
private:
|
|
Iterator m_iterator; // exposition
|
|
</pre>
|
|
<dl>
|
|
<dt>After the synopsis for <tt class="literal"><span class="pre">reverse_iterator</span></tt>, add:</dt>
|
|
<dd>If <tt class="literal"><span class="pre">Iterator</span></tt> models Random Access Traversal Iterator and Readable
|
|
Lvalue Iterator, then <tt class="literal"><span class="pre">iterator_category</span></tt> is convertible to
|
|
<tt class="literal"><span class="pre">random_access_iterator_tag</span></tt>. Otherwise, if
|
|
<tt class="literal"><span class="pre">Iterator</span></tt> models Bidirectional Traversal Iterator and Readable
|
|
Lvalue Iterator, then <tt class="literal"><span class="pre">iterator_category</span></tt> is convertible to
|
|
<tt class="literal"><span class="pre">bidirectional_iterator_tag</span></tt>. Otherwise, <tt class="literal"><span class="pre">iterator_category</span></tt> is
|
|
convertible to <tt class="literal"><span class="pre">input_iterator_tag</span></tt>.</dd>
|
|
<dt>Change:</dt>
|
|
<dd><p class="first"><strong>reverse_iterator requirements</strong></p>
|
|
<p class="last">The base <tt class="literal"><span class="pre">Iterator</span></tt> must be a model of Bidirectional Traversal
|
|
Iterator. The resulting <tt class="literal"><span class="pre">reverse_iterator</span></tt> will be a model of the
|
|
most refined standard traversal and access concepts that are modeled
|
|
by <tt class="literal"><span class="pre">Iterator</span></tt>.</p>
|
|
</dd>
|
|
<dt>to:</dt>
|
|
<dd><p class="first"><strong>reverse_iterator requirements</strong></p>
|
|
<p class="last"><tt class="literal"><span class="pre">Iterator</span></tt> must be a model of Bidirectional Traversal Iterator.</p>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
<div class="topic">
|
|
<p class="topic-title first"><tt class="literal"><span class="pre">reverse_iterator</span></tt> models</p>
|
|
<blockquote>
|
|
<p>A specialization of <tt class="literal"><span class="pre">reverse_iterator</span></tt> models the same iterator
|
|
traversal and iterator access concepts modeled by its <tt class="literal"><span class="pre">Iterator</span></tt>
|
|
argument. In addition, it may model old iterator concepts
|
|
specified in the following table:</p>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="53%" />
|
|
<col width="47%" />
|
|
</colgroup>
|
|
<thead valign="bottom">
|
|
<tr><th>If <tt class="literal"><span class="pre">I</span></tt> models</th>
|
|
<th>then <tt class="literal"><span class="pre">reverse_iterator<I></span></tt> models</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody valign="top">
|
|
<tr><td>Readable Lvalue Iterator,
|
|
Bidirectional Traversal Iterator</td>
|
|
<td>Bidirectional Iterator</td>
|
|
</tr>
|
|
<tr><td>Writable Lvalue Iterator,
|
|
Bidirectional Traversal Iterator</td>
|
|
<td>Mutable Bidirectional Iterator</td>
|
|
</tr>
|
|
<tr><td>Readable Lvalue Iterator,
|
|
Random Access Traversal Iterator</td>
|
|
<td>Random Access Iterator</td>
|
|
</tr>
|
|
<tr><td>Writable Lvalue Iterator,
|
|
Random Access Traversal Iterator</td>
|
|
<td>Mutable Random Access Iterator</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><tt class="literal"><span class="pre">reverse_iterator<X></span></tt> is interoperable with
|
|
<tt class="literal"><span class="pre">reverse_iterator<Y></span></tt> if and only if <tt class="literal"><span class="pre">X</span></tt> is interoperable with
|
|
<tt class="literal"><span class="pre">Y</span></tt>.</p>
|
|
</blockquote>
|
|
<dl>
|
|
<dt>Change:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">reverse_iterator</span></tt> with a
|
|
default constructed base object.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>to:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Constructs an instance of <tt class="literal"><span class="pre">reverse_iterator</span></tt> with <tt class="literal"><span class="pre">m_iterator</span></tt>
|
|
default constructed.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>Change:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Constructs an instance of <tt class="literal"><span class="pre">reverse_iterator</span></tt> with a
|
|
base object copy constructed from <tt class="literal"><span class="pre">x</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>to:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Constructs an instance of <tt class="literal"><span class="pre">reverse_iterator</span></tt> with a
|
|
<tt class="literal"><span class="pre">m_iterator</span></tt> constructed from <tt class="literal"><span class="pre">x</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>Change:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">reverse_iterator</span></tt> that is a copy of <tt class="literal"><span class="pre">r</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>to:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Constructs instance of <tt class="literal"><span class="pre">reverse_iterator</span></tt> whose
|
|
<tt class="literal"><span class="pre">m_iterator</span></tt> subobject is constructed from <tt class="literal"><span class="pre">y.base()</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>At the end of the operations for <tt class="literal"><span class="pre">reverse_iterator</span></tt>, add:</dt>
|
|
<dd><p class="first"><tt class="literal"><span class="pre">Iterator</span> <span class="pre">const&</span> <span class="pre">base()</span> <span class="pre">const;</span></tt></p>
|
|
<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">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">m_iterator</span></tt></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><tt class="literal"><span class="pre">reference</span> <span class="pre">operator*()</span> <span class="pre">const;</span></tt></p>
|
|
<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">Effects:</th><td class="field-body"></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<pre class="literal-block">
|
|
Iterator tmp = m_iterator;
|
|
return *--tmp;
|
|
</pre>
|
|
<p><tt class="literal"><span class="pre">reverse_iterator&</span> <span class="pre">operator++();</span></tt></p>
|
|
<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">Effects:</th><td class="field-body"><tt class="literal"><span class="pre">--m_iterator</span></tt></td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">*this</span></tt></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><tt class="literal"><span class="pre">reverse_iterator&</span> <span class="pre">operator--();</span></tt></p>
|
|
<table class="last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Effects:</th><td class="field-body"><tt class="literal"><span class="pre">++m_iterator</span></tt></td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">*this</span></tt></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
</dl>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
class transform_iterator
|
|
: public iterator_adaptor</* see discussion */>
|
|
{
|
|
friend class iterator_core_access;
|
|
</pre>
|
|
<p>to:</p>
|
|
<pre class="literal-block">
|
|
class transform_iterator
|
|
{
|
|
public:
|
|
typedef /* see below */ value_type;
|
|
typedef /* see below */ reference;
|
|
typedef /* see below */ pointer;
|
|
typedef iterator_traits<Iterator>::difference_type difference_type;
|
|
typedef /* see below */ iterator_category;
|
|
</pre>
|
|
<p>After <tt class="literal"><span class="pre">UnaryFunction</span> <span class="pre">functor()</span> <span class="pre">const;</span></tt> add:</p>
|
|
<pre class="literal-block">
|
|
Iterator const& base() const;
|
|
reference operator*() const;
|
|
transform_iterator& operator++();
|
|
transform_iterator& operator--();
|
|
</pre>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
private:
|
|
typename transform_iterator::value_type dereference() const;
|
|
UnaryFunction m_f;
|
|
};
|
|
</pre>
|
|
<p>to:</p>
|
|
<pre class="literal-block">
|
|
private:
|
|
Iterator m_iterator; // exposition only
|
|
UnaryFunction m_f; // exposition only
|
|
};
|
|
</pre>
|
|
<dl>
|
|
<dt>After the synopsis, add:</dt>
|
|
<dd>If <tt class="literal"><span class="pre">Iterator</span></tt> models Readable Lvalue Iterator and if <tt class="literal"><span class="pre">Iterator</span></tt>
|
|
models Random Access Traversal Iterator, then <tt class="literal"><span class="pre">iterator_category</span></tt> is
|
|
convertible to <tt class="literal"><span class="pre">random_access_iterator_tag</span></tt>. Otherwise, if
|
|
<tt class="literal"><span class="pre">Iterator</span></tt> models Bidirectional Traversal Iterator, then
|
|
<tt class="literal"><span class="pre">iterator_category</span></tt> is convertible to
|
|
<tt class="literal"><span class="pre">bidirectional_iterator_tag</span></tt>. Otherwise <tt class="literal"><span class="pre">iterator_category</span></tt> is
|
|
convertible to <tt class="literal"><span class="pre">forward_iterator_tag</span></tt>. If <tt class="literal"><span class="pre">Iterator</span></tt> does not
|
|
model Readable Lvalue Iterator then <tt class="literal"><span class="pre">iterator_category</span></tt> is
|
|
convertible to <tt class="literal"><span class="pre">input_iterator_tag</span></tt>.</dd>
|
|
<dt>In the requirements section, change:</dt>
|
|
<dd><p class="first">The type <tt class="literal"><span class="pre">Iterator</span></tt> must at least model Readable Iterator. The
|
|
resulting <tt class="literal"><span class="pre">transform_iterator</span></tt> models the most refined of the
|
|
following that is also modeled by <tt class="literal"><span class="pre">Iterator</span></tt>.</p>
|
|
<blockquote>
|
|
<ul class="simple">
|
|
<li>Writable Lvalue Iterator if
|
|
<tt class="literal"><span class="pre">result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type</span></tt>
|
|
is a non-const reference.</li>
|
|
<li>Readable Lvalue Iterator if
|
|
<tt class="literal"><span class="pre">result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type</span></tt>
|
|
is a const reference.</li>
|
|
<li>Readable Iterator otherwise.</li>
|
|
</ul>
|
|
</blockquote>
|
|
<p>The <tt class="literal"><span class="pre">transform_iterator</span></tt> models the most refined standard traversal
|
|
concept that is modeled by <tt class="literal"><span class="pre">Iterator</span></tt>.</p>
|
|
<p class="last">The <tt class="literal"><span class="pre">reference</span></tt> type of <tt class="literal"><span class="pre">transform_iterator</span></tt> is
|
|
<tt class="literal"><span class="pre">result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type</span></tt>.
|
|
The <tt class="literal"><span class="pre">value_type</span></tt> is <tt class="literal"><span class="pre">remove_cv<remove_reference<reference></span> <span class="pre">>::type</span></tt>.</p>
|
|
</dd>
|
|
<dt>to:</dt>
|
|
<dd>The argument <tt class="literal"><span class="pre">Iterator</span></tt> shall model Readable Iterator.</dd>
|
|
</dl>
|
|
<p>After the requirements section, add:</p>
|
|
</div>
|
|
<div class="topic">
|
|
<p class="topic-title first"><tt class="literal"><span class="pre">transform_iterator</span></tt> models</p>
|
|
<blockquote>
|
|
<p>The resulting <tt class="literal"><span class="pre">transform_iterator</span></tt> models the most refined of the
|
|
following options that is also modeled by <tt class="literal"><span class="pre">Iterator</span></tt>.</p>
|
|
<blockquote>
|
|
<ul class="simple">
|
|
<li>Writable Lvalue Iterator if
|
|
<tt class="literal"><span class="pre">transform_iterator::reference</span></tt> is a non-const
|
|
reference.</li>
|
|
<li>Readable Lvalue Iterator if
|
|
<tt class="literal"><span class="pre">transform_iterator::reference</span></tt> is a const reference.</li>
|
|
<li>Readable Iterator otherwise.</li>
|
|
</ul>
|
|
</blockquote>
|
|
<p>The <tt class="literal"><span class="pre">transform_iterator</span></tt> models the most refined standard traversal
|
|
concept that is modeled by the <tt class="literal"><span class="pre">Iterator</span></tt> argument.</p>
|
|
<p>If <tt class="literal"><span class="pre">transform_iterator</span></tt> is a model of Readable Lvalue Iterator then
|
|
it models the following original iterator concepts depending on what
|
|
the <tt class="literal"><span class="pre">Iterator</span></tt> argument models.</p>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="50%" />
|
|
<col width="50%" />
|
|
</colgroup>
|
|
<thead valign="bottom">
|
|
<tr><th>If <tt class="literal"><span class="pre">Iterator</span></tt> models</th>
|
|
<th>then <tt class="literal"><span class="pre">transform_iterator</span></tt> models</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody valign="top">
|
|
<tr><td>Single Pass Iterator</td>
|
|
<td>Input Iterator</td>
|
|
</tr>
|
|
<tr><td>Forward Traversal Iterator</td>
|
|
<td>Forward Iterator</td>
|
|
</tr>
|
|
<tr><td>Bidirectional Traversal Iterator</td>
|
|
<td>Bidirectional Iterator</td>
|
|
</tr>
|
|
<tr><td>Random Access Traversal Iterator</td>
|
|
<td>Random Access Iterator</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>If <tt class="literal"><span class="pre">transform_iterator</span></tt> models Writable Lvalue Iterator then it is a
|
|
mutable iterator (as defined in the old iterator requirements).</p>
|
|
<p><tt class="literal"><span class="pre">transform_iterator<F1,</span> <span class="pre">X,</span> <span class="pre">R1,</span> <span class="pre">V1></span></tt> is interoperable with
|
|
<tt class="literal"><span class="pre">transform_iterator<F2,</span> <span class="pre">Y,</span> <span class="pre">R2,</span> <span class="pre">V2></span></tt> if and only if <tt class="literal"><span class="pre">X</span></tt> is
|
|
interoperable with <tt class="literal"><span class="pre">Y</span></tt>.</p>
|
|
</blockquote>
|
|
<p>Remove the private operations section heading and remove:</p>
|
|
<pre class="literal-block">
|
|
``typename transform_iterator::value_type dereference() const;``
|
|
|
|
:Returns: ``m_f(transform_iterator::dereference());``
|
|
</pre>
|
|
<p>After the entry for <tt class="literal"><span class="pre">functor()</span></tt>, add:</p>
|
|
<pre class="literal-block">
|
|
``Iterator const& base() const;``
|
|
|
|
:Returns: ``m_iterator``
|
|
|
|
|
|
``reference operator*() const;``
|
|
|
|
:Returns: ``m_f(*m_iterator)``
|
|
|
|
|
|
``transform_iterator& operator++();``
|
|
|
|
:Effects: ``++m_iterator``
|
|
:Returns: ``*this``
|
|
|
|
|
|
``transform_iterator& operator--();``
|
|
|
|
:Effects: ``--m_iterator``
|
|
:Returns: ``*this``
|
|
</pre>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
template <class Predicate, class Iterator>
|
|
class filter_iterator
|
|
: public iterator_adaptor<
|
|
filter_iterator<Predicate, Iterator>, Iterator
|
|
, use_default
|
|
, /* see details */
|
|
>
|
|
{
|
|
public:
|
|
</pre>
|
|
<p>to:</p>
|
|
<pre class="literal-block">
|
|
template <class Predicate, class Iterator>
|
|
class filter_iterator
|
|
{
|
|
public:
|
|
typedef iterator_traits<Iterator>::value_type value_type;
|
|
typedef iterator_traits<Iterator>::reference reference;
|
|
typedef iterator_traits<Iterator>::pointer pointer;
|
|
typedef iterator_traits<Iterator>::difference_type difference_type;
|
|
typedef /* see below */ iterator_category;
|
|
</pre>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
private: // as-if specification
|
|
void increment()
|
|
{
|
|
++(this->base_reference());
|
|
satisfy_predicate();
|
|
}
|
|
|
|
void satisfy_predicate()
|
|
{
|
|
while (this->base() != this->m_end && !this->m_predicate(*this->base()))
|
|
++(this->base_reference());
|
|
}
|
|
|
|
Predicate m_predicate;
|
|
Iterator m_end;
|
|
</pre>
|
|
<p>to:</p>
|
|
<pre class="literal-block">
|
|
Iterator const& base() const;
|
|
reference operator*() const;
|
|
filter_iterator& operator++();
|
|
private:
|
|
Predicate m_pred; // exposition only
|
|
Iterator m_iter; // exposition only
|
|
Iterator m_end; // exposition only
|
|
</pre>
|
|
<dl>
|
|
<dt>Change:</dt>
|
|
<dd>The base <tt class="literal"><span class="pre">Iterator</span></tt> parameter must be a model of Readable
|
|
Iterator and Single Pass Iterator. The resulting
|
|
<tt class="literal"><span class="pre">filter_iterator</span></tt> will be a model of Forward Traversal Iterator
|
|
if <tt class="literal"><span class="pre">Iterator</span></tt> is, otherwise the <tt class="literal"><span class="pre">filter_iterator</span></tt> will be a
|
|
model of Single Pass Iterator. The access category of the
|
|
<tt class="literal"><span class="pre">filter_iterator</span></tt> will be the same as the access category of
|
|
<tt class="literal"><span class="pre">Iterator</span></tt>.</dd>
|
|
<dt>to:</dt>
|
|
<dd>The <tt class="literal"><span class="pre">Iterator</span></tt> argument shall meet the requirements of Readable
|
|
Iterator and Single Pass Iterator or it shall meet the requirements of
|
|
Input Iterator.</dd>
|
|
</dl>
|
|
<p>After the requirements section, add:</p>
|
|
</div>
|
|
<div class="topic">
|
|
<p class="topic-title first"><tt class="literal"><span class="pre">filter_iterator</span></tt> models</p>
|
|
<blockquote>
|
|
<p>The concepts that <tt class="literal"><span class="pre">filter_iterator</span></tt> models are dependent on which
|
|
concepts the <tt class="literal"><span class="pre">Iterator</span></tt> argument models, as specified in the
|
|
following tables.</p>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="33%" />
|
|
<col width="67%" />
|
|
</colgroup>
|
|
<thead valign="bottom">
|
|
<tr><th>If <tt class="literal"><span class="pre">Iterator</span></tt> models</th>
|
|
<th>then <tt class="literal"><span class="pre">filter_iterator</span></tt> models</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody valign="top">
|
|
<tr><td>Single Pass Iterator</td>
|
|
<td>Single Pass Iterator</td>
|
|
</tr>
|
|
<tr><td>Forward Traversal Iterator</td>
|
|
<td>Forward Traversal Iterator</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="41%" />
|
|
<col width="59%" />
|
|
</colgroup>
|
|
<thead valign="bottom">
|
|
<tr><th>If <tt class="literal"><span class="pre">Iterator</span></tt> models</th>
|
|
<th>then <tt class="literal"><span class="pre">filter_iterator</span></tt> models</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody valign="top">
|
|
<tr><td>Readable Iterator</td>
|
|
<td>Readable Iterator</td>
|
|
</tr>
|
|
<tr><td>Writable Iterator</td>
|
|
<td>Writable Iterator</td>
|
|
</tr>
|
|
<tr><td>Lvalue Iterator</td>
|
|
<td>Lvalue Iterator</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="63%" />
|
|
<col width="38%" />
|
|
</colgroup>
|
|
<thead valign="bottom">
|
|
<tr><th>If <tt class="literal"><span class="pre">Iterator</span></tt> models</th>
|
|
<th>then <tt class="literal"><span class="pre">filter_iterator</span></tt> models</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody valign="top">
|
|
<tr><td>Readable Iterator, Single Pass Iterator</td>
|
|
<td>Input Iterator</td>
|
|
</tr>
|
|
<tr><td>Readable Lvalue Iterator, Forward Traversal Iterator</td>
|
|
<td>Forward Iterator</td>
|
|
</tr>
|
|
<tr><td>Writable Lvalue Iterator, Forward Traversal Iterator</td>
|
|
<td>Mutable Forward Iterator</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><tt class="literal"><span class="pre">filter_iterator<P1,</span> <span class="pre">X></span></tt> is interoperable with <tt class="literal"><span class="pre">filter_iterator<P2,</span> <span class="pre">Y></span></tt>
|
|
if and only if <tt class="literal"><span class="pre">X</span></tt> is interoperable with <tt class="literal"><span class="pre">Y</span></tt>.</p>
|
|
</blockquote>
|
|
<dl>
|
|
<dt>Change:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">a <tt class="literal"><span class="pre">filter_iterator</span></tt> whose
|
|
predicate is a default constructed <tt class="literal"><span class="pre">Predicate</span></tt> and
|
|
whose <tt class="literal"><span class="pre">end</span></tt> is a default constructed <tt class="literal"><span class="pre">Iterator</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>to:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Constructs a <tt class="literal"><span class="pre">filter_iterator</span></tt> whose``m_pred``, <tt class="literal"><span class="pre">m_iter</span></tt>, and <tt class="literal"><span class="pre">m_end</span></tt>
|
|
members are a default constructed.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>Change:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">A <tt class="literal"><span class="pre">filter_iterator</span></tt> at position <tt class="literal"><span class="pre">x</span></tt> that filters according
|
|
to predicate <tt class="literal"><span class="pre">f</span></tt> and that will not increment past <tt class="literal"><span class="pre">end</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>to:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Constructs a <tt class="literal"><span class="pre">filter_iterator</span></tt> where <tt class="literal"><span class="pre">m_iter</span></tt> is either
|
|
the first position in the range <tt class="literal"><span class="pre">[x,end)</span></tt> such that <tt class="literal"><span class="pre">f(*m_iter)</span> <span class="pre">==</span> <span class="pre">true</span></tt>
|
|
or else``m_iter == end``. The member <tt class="literal"><span class="pre">m_pred</span></tt> is constructed from
|
|
<tt class="literal"><span class="pre">f</span></tt> and <tt class="literal"><span class="pre">m_end</span></tt> from <tt class="literal"><span class="pre">end</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>Change:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">A <tt class="literal"><span class="pre">filter_iterator</span></tt> at position <tt class="literal"><span class="pre">x</span></tt> that filters
|
|
according to a default constructed <tt class="literal"><span class="pre">Predicate</span></tt>
|
|
and that will not increment past <tt class="literal"><span class="pre">end</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>to:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Constructs a <tt class="literal"><span class="pre">filter_iterator</span></tt> where <tt class="literal"><span class="pre">m_iter</span></tt> is either
|
|
the first position in the range <tt class="literal"><span class="pre">[x,end)</span></tt> such that <tt class="literal"><span class="pre">m_pred(*m_iter)</span> <span class="pre">==</span> <span class="pre">true</span></tt>
|
|
or else``m_iter == end``. The member <tt class="literal"><span class="pre">m_pred</span></tt> is default constructed.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>Change:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">A copy of iterator <tt class="literal"><span class="pre">t</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>to:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Constructs a filter iterator whose members are copied from <tt class="literal"><span class="pre">t</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>Change:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">A copy of the predicate object used to construct <tt class="literal"><span class="pre">*this</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>to:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">m_pred</span></tt></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>Change:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">The object <tt class="literal"><span class="pre">end</span></tt> used to construct <tt class="literal"><span class="pre">*this</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>to:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">m_end</span></tt></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
</dl>
|
|
<p>At the end of the operations section, add:</p>
|
|
<blockquote>
|
|
<p><tt class="literal"><span class="pre">reference</span> <span class="pre">operator*()</span> <span class="pre">const;</span></tt></p>
|
|
<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">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">*m_iter</span></tt></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><tt class="literal"><span class="pre">filter_iterator&</span> <span class="pre">operator++();</span></tt></p>
|
|
<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">Effects:</th><td class="field-body">Increments <tt class="literal"><span class="pre">m_iter</span></tt> and then continues to
|
|
increment <tt class="literal"><span class="pre">m_iter</span></tt> until either <tt class="literal"><span class="pre">m_iter</span> <span class="pre">==</span> <span class="pre">m_end</span></tt>
|
|
or <tt class="literal"><span class="pre">m_pred(*m_iter)</span> <span class="pre">==</span> <span class="pre">true</span></tt>.</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">*this</span></tt></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
class counting_iterator
|
|
: public iterator_adaptor<
|
|
counting_iterator<Incrementable, Access, Traversal, Difference>
|
|
, Incrementable
|
|
, Incrementable
|
|
, Access
|
|
, /* see details for traversal category */
|
|
, Incrementable const&
|
|
, Incrementable const*
|
|
, /* distance = Difference or a signed integral type */>
|
|
{
|
|
friend class iterator_core_access;
|
|
public:
|
|
</pre>
|
|
<p>to:</p>
|
|
<pre class="literal-block">
|
|
class counting_iterator
|
|
{
|
|
public:
|
|
typedef Incrementable value_type;
|
|
typedef const Incrementable& reference;
|
|
typedef const Incrementable* pointer;
|
|
typedef /* see below */ difference_type;
|
|
typedef /* see below */ iterator_category;
|
|
</pre>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
private:
|
|
typename counting_iterator::reference dereference() const
|
|
{
|
|
return this->base_reference();
|
|
}
|
|
</pre>
|
|
<p>to:</p>
|
|
<pre class="literal-block">
|
|
Incrementable const& base() const;
|
|
reference operator*() const;
|
|
counting_iterator& operator++();
|
|
counting_iterator& operator--();
|
|
private:
|
|
Incrementable m_inc; // exposition
|
|
</pre>
|
|
<p>After the synopsis, add:</p>
|
|
<blockquote>
|
|
<p>If the <tt class="literal"><span class="pre">Difference</span></tt> argument is <tt class="literal"><span class="pre">use_default</span></tt> then
|
|
<tt class="literal"><span class="pre">difference_type</span></tt> is an unspecified signed integral
|
|
type. Otherwise <tt class="literal"><span class="pre">difference_type</span></tt> is <tt class="literal"><span class="pre">Difference</span></tt>.</p>
|
|
<p><tt class="literal"><span class="pre">iterator_category</span></tt> is determined according to the following
|
|
algorithm:</p>
|
|
<pre class="literal-block">
|
|
if (CategoryOrTraversal is not use_default)
|
|
return CategoryOrTraversal
|
|
else if (numeric_limits<Incrementable>::is_specialized)
|
|
return <em>iterator-category</em>(
|
|
random_access_traversal_tag, Incrementable, const Incrementable&)
|
|
else
|
|
return <em>iterator-category</em>(
|
|
iterator_traversal<Incrementable>::type,
|
|
Incrementable, const Incrementable&)
|
|
</pre>
|
|
</blockquote>
|
|
<dl>
|
|
<dt>Change:</dt>
|
|
<dd><dl class="first last">
|
|
<dt>[<em>Note:</em> implementers are encouraged to provide an implementation of</dt>
|
|
<dd><tt class="literal"><span class="pre">distance_to</span></tt> and a <tt class="literal"><span class="pre">difference_type</span></tt> that avoids overflows in
|
|
the cases when the <tt class="literal"><span class="pre">Incrementable</span></tt> type is a numeric type.]</dd>
|
|
</dl>
|
|
</dd>
|
|
<dt>to:</dt>
|
|
<dd><dl class="first last">
|
|
<dt>[<em>Note:</em> implementers are encouraged to provide an implementation of</dt>
|
|
<dd><tt class="literal"><span class="pre">operator-</span></tt> and a <tt class="literal"><span class="pre">difference_type</span></tt> that avoid overflows in
|
|
the cases where <tt class="literal"><span class="pre">std::numeric_limits<Incrementable>::is_specialized</span></tt>
|
|
is true.]</dd>
|
|
</dl>
|
|
</dd>
|
|
<dt>Change:</dt>
|
|
<dd><p class="first">The <tt class="literal"><span class="pre">Incrementable</span></tt> type must be Default Constructible, Copy
|
|
Constructible, and Assignable. The default distance is
|
|
an implementation defined signed integegral type.</p>
|
|
<p class="last">The resulting <tt class="literal"><span class="pre">counting_iterator</span></tt> models Readable Lvalue Iterator.</p>
|
|
</dd>
|
|
<dt>to:</dt>
|
|
<dd>The <tt class="literal"><span class="pre">Incrementable</span></tt> argument shall be Copy Constructible and Assignable.</dd>
|
|
<dt>Change:</dt>
|
|
<dd>Furthermore, if you wish to create a counting iterator that is a Forward
|
|
Traversal Iterator, then the following expressions must be valid:</dd>
|
|
<dt>to:</dt>
|
|
<dd>If <tt class="literal"><span class="pre">iterator_category</span></tt> is convertible to <tt class="literal"><span class="pre">forward_iterator_tag</span></tt>
|
|
or <tt class="literal"><span class="pre">forward_traversal_tag</span></tt>, the following must be well-formed:</dd>
|
|
<dt>Change:</dt>
|
|
<dd>If you wish to create a counting iterator that is a
|
|
Bidirectional Traversal Iterator, then pre-decrement is also required:</dd>
|
|
<dt>to:</dt>
|
|
<dd>If <tt class="literal"><span class="pre">iterator_category</span></tt> is convertible to
|
|
<tt class="literal"><span class="pre">bidirectional_iterator_tag</span></tt> or <tt class="literal"><span class="pre">bidirectional_traversal_tag</span></tt>,
|
|
the following expression must also be well-formed:</dd>
|
|
<dt>Change:</dt>
|
|
<dd>If you wish to create a counting iterator that is a Random Access
|
|
Traversal Iterator, then these additional expressions are also
|
|
required:</dd>
|
|
<dt>to:</dt>
|
|
<dd>If <tt class="literal"><span class="pre">iterator_category</span></tt> is convertible to
|
|
<tt class="literal"><span class="pre">random_access_iterator_tag</span></tt> or <tt class="literal"><span class="pre">random_access_traversal_tag</span></tt>,
|
|
the following must must also be valid:</dd>
|
|
</dl>
|
|
<p>After the requirements section, add:</p>
|
|
</div>
|
|
<div class="topic">
|
|
<p class="topic-title first"><tt class="literal"><span class="pre">counting_iterator</span></tt> models</p>
|
|
<blockquote>
|
|
<p>Specializations of <tt class="literal"><span class="pre">counting_iterator</span></tt> model Readable Lvalue
|
|
Iterator. In addition, they model the concepts corresponding to the
|
|
iterator tags to which their <tt class="literal"><span class="pre">iterator_category</span></tt> is convertible.
|
|
Also, if <tt class="literal"><span class="pre">CategoryOrTraversal</span></tt> is not <tt class="literal"><span class="pre">use_default</span></tt> then
|
|
<tt class="literal"><span class="pre">counting_iterator</span></tt> models the concept corresponding to the iterator
|
|
tag <tt class="literal"><span class="pre">CategoryOrTraversal</span></tt>. Otherwise, if
|
|
<tt class="literal"><span class="pre">numeric_limits<Incrementable>::is_specialized</span></tt>, then
|
|
<tt class="literal"><span class="pre">counting_iterator</span></tt> models Random Access Traversal Iterator.
|
|
Otherwise, <tt class="literal"><span class="pre">counting_iterator</span></tt> models the same iterator traversal
|
|
concepts modeled by <tt class="literal"><span class="pre">Incrementable</span></tt>.</p>
|
|
<p><tt class="literal"><span class="pre">counting_iterator<X,C1,D1></span></tt> is interoperable with
|
|
<tt class="literal"><span class="pre">counting_iterator<Y,C2,D2></span></tt> if and only if <tt class="literal"><span class="pre">X</span></tt> is
|
|
interoperable with <tt class="literal"><span class="pre">Y</span></tt>.</p>
|
|
</blockquote>
|
|
<p>At the begining of the operations section, add:</p>
|
|
<blockquote>
|
|
In addition to the operations required by the concepts modeled by
|
|
<tt class="literal"><span class="pre">counting_iterator</span></tt>, <tt class="literal"><span class="pre">counting_iterator</span></tt> provides the following
|
|
operations.</blockquote>
|
|
<dl>
|
|
<dt>Change:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">A default constructed instance of <tt class="literal"><span class="pre">counting_iterator</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>to:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">Incrementable</span></tt> is Default Constructible.</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Default construct the member <tt class="literal"><span class="pre">m_inc</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>Change:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">counting_iterator</span></tt> that is a copy of <tt class="literal"><span class="pre">rhs</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>to:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Construct member <tt class="literal"><span class="pre">m_inc</span></tt> from <tt class="literal"><span class="pre">rhs.m_inc</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>Change:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">counting_iterator</span></tt> with its base
|
|
object copy constructed from <tt class="literal"><span class="pre">x</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
<dt>to:</dt>
|
|
<dd><table class="first last field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Construct member <tt class="literal"><span class="pre">m_inc</span></tt> from <tt class="literal"><span class="pre">x</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</dd>
|
|
</dl>
|
|
<p>At the end of the operations section, add:</p>
|
|
<blockquote>
|
|
<p><tt class="literal"><span class="pre">reference</span> <span class="pre">operator*()</span> <span class="pre">const;</span></tt></p>
|
|
<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">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">m_inc</span></tt></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><tt class="literal"><span class="pre">counting_iterator&</span> <span class="pre">operator++();</span></tt></p>
|
|
<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">Effects:</th><td class="field-body"><tt class="literal"><span class="pre">++m_inc</span></tt></td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">*this</span></tt></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><tt class="literal"><span class="pre">counting_iterator&</span> <span class="pre">operator--();</span></tt></p>
|
|
<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">Effects:</th><td class="field-body"><tt class="literal"><span class="pre">--m_inc</span></tt></td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">*this</span></tt></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><tt class="literal"><span class="pre">Incrementable</span> <span class="pre">const&</span> <span class="pre">base()</span> <span class="pre">const;</span></tt></p>
|
|
<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">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">m_inc</span></tt></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
</div>
|
|
</div>
|
|
<div class="section" id="x-problem-with-specification-of-a-m-in-readable-iterator">
|
|
<h2><a class="toc-backref" href="#id40" name="x-problem-with-specification-of-a-m-in-readable-iterator">9.38x Problem with specification of a->m in Readable Iterator</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Howard Hinnant</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Status:</th><td class="field-body">New</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>c++std-lib-12585:</p>
|
|
<p>Readable Iterator Requirements says:</p>
|
|
<blockquote>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="13%" />
|
|
<col width="10%" />
|
|
<col width="77%" />
|
|
</colgroup>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">a->m</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">U&</span></tt></td>
|
|
<td>pre: <tt class="literal"><span class="pre">(*a).m</span></tt> is well-defined. Equivalent to <tt class="literal"><span class="pre">(*a).m</span></tt></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>Do we mean to outlaw iterators with proxy references from meeting
|
|
the readable requirements?</p>
|
|
<p>Would it be better for the requirements to read <tt class="literal"><span class="pre">static_cast<T>(*a).m</span></tt>
|
|
instead of <tt class="literal"><span class="pre">(*a).m</span></tt> ?</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body">NAD.</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Rationale:</th><td class="field-body"><p class="first">We think you're misreading "pre:".
|
|
If <tt class="literal"><span class="pre">(*a).m</span></tt> is not well defined, then the iterator is not
|
|
required to provide <tt class="literal"><span class="pre">a->m</span></tt>. So a proxy iterator is not
|
|
required to provide <tt class="literal"><span class="pre">a->m</span></tt>.</p>
|
|
<p class="last">As an aside, it is possible for proxy iterators to
|
|
support <tt class="literal"><span class="pre">-></span></tt>, so changing the requirements to
|
|
read <tt class="literal"><span class="pre">static_cast<T>(*a).m</span></tt> is interesting.
|
|
However, such a change to Readable Iterator would
|
|
mean that it no longer corresponds to the
|
|
input iterator requirements. So old iterators would not
|
|
necessarily conform to new iterator requirements.</p>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="x-counting-iterator-traversal-argument-unspecified">
|
|
<h2><a class="toc-backref" href="#id41" name="x-counting-iterator-traversal-argument-unspecified">9.39x counting_iterator Traversal argument unspecified</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>c++std-lib-12635:</p>
|
|
<p>counting_iterator takes an argument for its Traversal type, with a
|
|
default value of use_default. It is derived from an instance of
|
|
iterator_adaptor, where the argument passed for the Traversal type
|
|
is described as "<tt class="literal"><span class="pre">/*</span> <span class="pre">see</span> <span class="pre">details</span> <span class="pre">for</span> <span class="pre">traversal</span> <span class="pre">category</span>
|
|
<span class="pre">*/</span></tt>". The details for counting_iterator describe constraints on
|
|
the Incrementable type imposed by various traversal
|
|
categories. There is no description of what the argument to
|
|
iterator_adaptor should be.</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body">We no longer inherit from iterator_adaptor. So instead,
|
|
we specify the iterator_category in terms of the Traversal type
|
|
(which is now called CategoryOrTraversal). Also the
|
|
requirements and models section was reorganized to
|
|
match these changes and to make more sense.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="x-indirect-iterator-requirements-muddled">
|
|
<h2><a class="toc-backref" href="#id42" name="x-indirect-iterator-requirements-muddled">9.40x indirect_iterator requirements muddled</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>c++std-lib-12640:</p>
|
|
<blockquote>
|
|
<blockquote>
|
|
The value_type of the Iterator template parameter should itself
|
|
be dereferenceable. The return type of the <tt class="literal"><span class="pre">operator*</span></tt> for
|
|
the value_type must be the same type as the Reference template
|
|
parameter.</blockquote>
|
|
<p>I'd say this a bit differently, to emphasize what's required:
|
|
iterator_traits<Iterator>::value_type must be dereferenceable.
|
|
The Reference template parameter must be the same type as
|
|
<tt class="literal"><span class="pre">*iterator_traits<Iterator>::value_type()</span></tt>.</p>
|
|
<blockquote>
|
|
The Value template parameter will be the value_type for the
|
|
indirect_iterator, unless Value is const. If Value is const X, then
|
|
value_type will be non- const X.</blockquote>
|
|
<p>Also non-volatile, right? In other words, if Value isn't use_default, it
|
|
just gets passed as the Value argument for iterator_adaptor.</p>
|
|
<blockquote>
|
|
<p>The default for Value is:</p>
|
|
<pre class="literal-block">
|
|
iterator_traits< iterator_traits<Iterator>::value_type >::value_type
|
|
</pre>
|
|
<p>If the default is used for Value, then there must be a valid
|
|
specialization of iterator_traits for the value type of the
|
|
base iterator.</p>
|
|
</blockquote>
|
|
<p>The earlier requirement is that
|
|
<tt class="literal"><span class="pre">iterator_traits<Iterator>::value_type</span></tt> must be
|
|
dereferenceable. Now it's being treated as an iterator. Is this
|
|
just a pun, or is <tt class="literal"><span class="pre">iterator_traits<Iterator>::value_type</span></tt>
|
|
required to be some form of iterator? If it's the former we need
|
|
to find a different way to say it. If it's the latter we need to
|
|
say so.</p>
|
|
</blockquote>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">Change:</p>
|
|
<blockquote>
|
|
<p>The <tt class="literal"><span class="pre">value_type</span></tt> of the <tt class="literal"><span class="pre">Iterator</span></tt> template parameter
|
|
should itself be dereferenceable. The return type of the
|
|
<tt class="literal"><span class="pre">operator*</span></tt> for the <tt class="literal"><span class="pre">value_type</span></tt> must be the same type as
|
|
the <tt class="literal"><span class="pre">Reference</span></tt> template parameter. The <tt class="literal"><span class="pre">Value</span></tt> template
|
|
parameter will be the <tt class="literal"><span class="pre">value_type</span></tt> for the
|
|
<tt class="literal"><span class="pre">indirect_iterator</span></tt>, unless <tt class="literal"><span class="pre">Value</span></tt> is const. If <tt class="literal"><span class="pre">Value</span></tt>
|
|
is <tt class="literal"><span class="pre">const</span> <span class="pre">X</span></tt>, then <tt class="literal"><span class="pre">value_type</span></tt> will be <em>non-</em> <tt class="literal"><span class="pre">const</span> <span class="pre">X</span></tt>.
|
|
The default for <tt class="literal"><span class="pre">Value</span></tt> is:</p>
|
|
<pre class="literal-block">
|
|
iterator_traits< iterator_traits<Iterator>::value_type >::value_type
|
|
</pre>
|
|
<p>If the default is used for <tt class="literal"><span class="pre">Value</span></tt>, then there must be a
|
|
valid specialization of <tt class="literal"><span class="pre">iterator_traits</span></tt> for the value type
|
|
of the base iterator.</p>
|
|
<p>The <tt class="literal"><span class="pre">Reference</span></tt> parameter will be the <tt class="literal"><span class="pre">reference</span></tt> type of the
|
|
<tt class="literal"><span class="pre">indirect_iterator</span></tt>. The default is <tt class="literal"><span class="pre">Value&</span></tt>.</p>
|
|
<p>The <tt class="literal"><span class="pre">Access</span></tt> and <tt class="literal"><span class="pre">Traversal</span></tt> parameters are passed
|
|
unchanged to the corresponding parameters of the
|
|
<tt class="literal"><span class="pre">iterator_adaptor</span></tt> base class, and the <tt class="literal"><span class="pre">Iterator</span></tt> parameter
|
|
is passed unchanged as the <tt class="literal"><span class="pre">Base</span></tt> parameter to the
|
|
<tt class="literal"><span class="pre">iterator_adaptor</span></tt> base class.</p>
|
|
</blockquote>
|
|
<p>to:</p>
|
|
<blockquote class="last">
|
|
<blockquote>
|
|
The expression <tt class="literal"><span class="pre">*v</span></tt>, where <tt class="literal"><span class="pre">v</span></tt> is an object of
|
|
<tt class="literal"><span class="pre">iterator_traits<Iterator>::value_type</span></tt>, shall be valid
|
|
expression and convertible to <tt class="literal"><span class="pre">reference</span></tt>. <tt class="literal"><span class="pre">Iterator</span></tt>
|
|
shall model the traversal concept indicated by
|
|
<tt class="literal"><span class="pre">iterator_category</span></tt>. <tt class="literal"><span class="pre">Value</span></tt>, <tt class="literal"><span class="pre">Reference</span></tt>, and
|
|
<tt class="literal"><span class="pre">Difference</span></tt> shall be chosen so that <tt class="literal"><span class="pre">value_type</span></tt>,
|
|
<tt class="literal"><span class="pre">reference</span></tt>, and <tt class="literal"><span class="pre">difference_type</span></tt> meet the requirements
|
|
indicated by <tt class="literal"><span class="pre">iterator_category</span></tt>.</blockquote>
|
|
<p>[Note: there are further requirements on the
|
|
<tt class="literal"><span class="pre">iterator_traits<Iterator>::value_type</span></tt> if the <tt class="literal"><span class="pre">Value</span></tt>
|
|
parameter is not <tt class="literal"><span class="pre">use_default</span></tt>, as implied by the algorithm
|
|
for deducing the default for the <tt class="literal"><span class="pre">value_type</span></tt> member.]</p>
|
|
</blockquote>
|
|
</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Rationale:</th><td class="field-body">Not included above is the specification of the
|
|
<tt class="literal"><span class="pre">value_type</span></tt>, <tt class="literal"><span class="pre">reference</span></tt>, etc., members, which is handled by
|
|
the changes in 9.37x.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="x-problem-with-transform-iterator-requirements">
|
|
<h2><a class="toc-backref" href="#id43" name="x-problem-with-transform-iterator-requirements">9.41x Problem with transform_iterator requirements</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>c++std-lib-12641:</p>
|
|
<blockquote>
|
|
The reference type of transform_iterator is <tt class="literal"><span class="pre">result_of<</span>
|
|
<span class="pre">UnaryFunction(iterator_traits<Iterator>::reference)</span>
|
|
<span class="pre">>::type</span></tt>. The <tt class="literal"><span class="pre">value_type</span></tt> is
|
|
<tt class="literal"><span class="pre">remove_cv<remove_reference<reference></span> <span class="pre">>::type</span></tt>.</blockquote>
|
|
<p>These are the defaults, right? If the user supplies their own types
|
|
that's what gets passed to iterator_adaptor. And again, the
|
|
specification should be in terms of the specialization of
|
|
iterator_adaptor, and not in terms of the result:</p>
|
|
<p>Reference argument to iterator_adaptor:</p>
|
|
<pre class="literal-block">
|
|
if (Reference != use_default)
|
|
Reference
|
|
else
|
|
result_of<
|
|
UnaryFunction(iterator_traits<Iterator>::reference)
|
|
>::type
|
|
</pre>
|
|
<p>Value argument to iterator_adaptor:</p>
|
|
<pre class="literal-block">
|
|
if (Value != use_default)
|
|
Value
|
|
else if (Reference != use_default)
|
|
remove_reference<reference>::type
|
|
else
|
|
remove_reference<
|
|
result_of<
|
|
UnaryFunction(iterator_traits<Iterator>::reference)
|
|
>::type
|
|
>::type
|
|
</pre>
|
|
<p>There's probably a better way to specify that last alternative, but
|
|
I've been at this too long, and it's all turning into a maze of
|
|
twisty passages, all alike.</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">Replace:</p>
|
|
<blockquote>
|
|
The reference type of transform_iterator is <tt class="literal"><span class="pre">result_of<</span>
|
|
<span class="pre">UnaryFunction(iterator_traits<Iterator>::reference)</span>
|
|
<span class="pre">>::type</span></tt>. The <tt class="literal"><span class="pre">value_type</span></tt> is
|
|
<tt class="literal"><span class="pre">remove_cv<remove_reference<reference></span> <span class="pre">>::type</span></tt>.</blockquote>
|
|
<p>with:</p>
|
|
<blockquote class="last">
|
|
<p>If <tt class="literal"><span class="pre">Reference</span></tt> is <tt class="literal"><span class="pre">use_default</span></tt> then the <tt class="literal"><span class="pre">reference</span></tt>
|
|
member of <tt class="literal"><span class="pre">transform_iterator</span></tt> is <tt class="literal"><span class="pre">result_of<</span>
|
|
<span class="pre">UnaryFunction(iterator_traits<Iterator>::reference)</span>
|
|
<span class="pre">>::type</span></tt>. Otherwise, <tt class="literal"><span class="pre">reference</span></tt> is <tt class="literal"><span class="pre">Reference</span></tt>.</p>
|
|
<p>If <tt class="literal"><span class="pre">Value</span></tt> is <tt class="literal"><span class="pre">use_default</span></tt> then the <tt class="literal"><span class="pre">value_type</span></tt>
|
|
member is <tt class="literal"><span class="pre">remove_cv<remove_reference<reference></span> <span class="pre">>::type</span></tt>.
|
|
Otherwise, <tt class="literal"><span class="pre">value_type</span></tt> is <tt class="literal"><span class="pre">Value</span></tt>.</p>
|
|
</blockquote>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="x-filter-iterator-details-unspecified">
|
|
<h2><a class="toc-backref" href="#id44" name="x-filter-iterator-details-unspecified">9.42x filter_iterator details unspecified</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Pete Becker</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>c++std-lib-12642:</p>
|
|
<p>The paper says:</p>
|
|
<pre class="literal-block">
|
|
template<class Predicate, class Iterator>
|
|
class filter_iterator
|
|
: public iterator_adaptor<
|
|
filter_iterator<Predicate, Iterator>,
|
|
Iterator,
|
|
use_default,
|
|
/* see details */ >
|
|
</pre>
|
|
<p>That comment covers the Access, Traversal, Reference, and Difference
|
|
arguments. The only specification for any of these in the details is:</p>
|
|
<blockquote>
|
|
The access category of the filter_iterator will be the same as
|
|
the access category of Iterator.</blockquote>
|
|
<p>Needs more.</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">Add to the synopsis:</p>
|
|
<pre class="literal-block">
|
|
typedef iterator_traits<Iterator>::value_type value_type;
|
|
typedef iterator_traits<Iterator>::reference reference;
|
|
typedef iterator_traits<Iterator>::pointer pointer;
|
|
typedef iterator_traits<Iterator>::difference_type difference_type;
|
|
typedef /* see below */ iterator_category;
|
|
</pre>
|
|
<p>and add just after the synopsis:</p>
|
|
<blockquote class="last">
|
|
If <tt class="literal"><span class="pre">Iterator</span></tt> models Readable Lvalue Iterator and Forward
|
|
Traversal Iterator then <tt class="literal"><span class="pre">iterator_category</span></tt> is convertible
|
|
to <tt class="literal"><span class="pre">std::forward_iterator_tag</span></tt>. Otherwise
|
|
<tt class="literal"><span class="pre">iterator_category</span></tt> is convertible to
|
|
<tt class="literal"><span class="pre">std::input_iterator_tag</span></tt>.</blockquote>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="x-transform-iterator-interoperability-too-restrictive">
|
|
<h2><a class="toc-backref" href="#id45" name="x-transform-iterator-interoperability-too-restrictive">9.43x transform_iterator interoperability too restrictive</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Jeremy Siek</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>We do not need to require that the function objects have the same
|
|
type, just that they be convertible.</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">Change:</p>
|
|
<pre class="literal-block">
|
|
template<class OtherIterator, class R2, class V2>
|
|
transform_iterator(
|
|
transform_iterator<UnaryFunction, OtherIterator, R2, V2> const& t
|
|
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
|
|
);
|
|
</pre>
|
|
<p>to:</p>
|
|
<pre class="last literal-block">
|
|
template<class F2, class I2, class R2, class V2>
|
|
transform_iterator(
|
|
transform_iterator<F2, I2, R2, V2> const& t
|
|
, typename enable_if_convertible<I2, Iterator>::type* = 0 // exposition only
|
|
, typename enable_if_convertible<F2, UnaryFunction>::type* = 0 // exposition only
|
|
);
|
|
</pre>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="y-indirect-iterator-and-smart-pointers">
|
|
<h2><a class="toc-backref" href="#id46" name="y-indirect-iterator-and-smart-pointers">9.44y <tt class="literal"><span class="pre">indirect_iterator</span></tt> and smart pointers</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Dave Abrahams</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><tt class="literal"><span class="pre">indirect_iterator</span></tt> should be able to iterate over containers of
|
|
smart pointers, but the mechanism that allows it was left out of
|
|
the specification, even though it's present in the Boost
|
|
specification</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">Add <tt class="literal"><span class="pre">pointee</span></tt> and <tt class="literal"><span class="pre">indirect_reference</span></tt>
|
|
to deal with this capability.</p>
|
|
<p>In [lib.iterator.helper.synopsis], add:</p>
|
|
<pre class="literal-block">
|
|
template <class Dereferenceable>
|
|
struct pointee;
|
|
|
|
template <class Dereferenceable>
|
|
struct indirect_reference;
|
|
</pre>
|
|
<p class="last">After <tt class="literal"><span class="pre">indirect_iterator</span></tt>'s abstract, add:</p>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<div class="topic">
|
|
<p class="topic-title first">Class template <tt class="literal"><span class="pre">pointee</span></tt></p>
|
|
<!-- Copyright David Abrahams 2004. Use, modification and distribution is -->
|
|
<!-- subject to the Boost Software License, Version 1.0. (See accompanying -->
|
|
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
|
<pre class="literal-block">
|
|
template <class Dereferenceable>
|
|
struct pointee
|
|
{
|
|
typedef /* see below */ type;
|
|
};
|
|
</pre>
|
|
<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">Requires:</th><td class="field-body">For an object <tt class="literal"><span class="pre">x</span></tt> of type <tt class="literal"><span class="pre">Dereferenceable</span></tt>, <tt class="literal"><span class="pre">*x</span></tt>
|
|
is well-formed. If <tt class="literal"><span class="pre">++x</span></tt> is ill-formed it shall neither be
|
|
ambiguous nor shall it violate access control, and
|
|
<tt class="literal"><span class="pre">Dereferenceable::element_type</span></tt> shall be an accessible type.
|
|
Otherwise <tt class="literal"><span class="pre">iterator_traits<Dereferenceable>::value_type</span></tt> shall
|
|
be well formed. [Note: These requirements need not apply to
|
|
explicit or partial specializations of <tt class="literal"><span class="pre">pointee</span></tt>]</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><tt class="literal"><span class="pre">type</span></tt> is determined according to the following algorithm, where
|
|
<tt class="literal"><span class="pre">x</span></tt> is an object of type <tt class="literal"><span class="pre">Dereferenceable</span></tt>:</p>
|
|
<pre class="literal-block">
|
|
if ( ++x is ill-formed )
|
|
{
|
|
return ``Dereferenceable::element_type``
|
|
}
|
|
else if (``*x`` is a mutable reference to
|
|
std::iterator_traits<Dereferenceable>::value_type)
|
|
{
|
|
return iterator_traits<Dereferenceable>::value_type
|
|
}
|
|
else
|
|
{
|
|
return iterator_traits<Dereferenceable>::value_type const
|
|
}
|
|
</pre>
|
|
</div>
|
|
<div class="topic">
|
|
<p class="topic-title first">Class template <tt class="literal"><span class="pre">indirect_reference</span></tt></p>
|
|
<!-- Copyright David Abrahams 2004. Use, modification and distribution is -->
|
|
<!-- subject to the Boost Software License, Version 1.0. (See accompanying -->
|
|
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
|
<pre class="literal-block">
|
|
template <class Dereferenceable>
|
|
struct indirect_reference
|
|
{
|
|
typedef /* see below */ type;
|
|
};
|
|
</pre>
|
|
<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">Requires:</th><td class="field-body">For an object <tt class="literal"><span class="pre">x</span></tt> of type <tt class="literal"><span class="pre">Dereferenceable</span></tt>, <tt class="literal"><span class="pre">*x</span></tt>
|
|
is well-formed. If <tt class="literal"><span class="pre">++x</span></tt> is ill-formed it shall neither be
|
|
ambiguous nor shall it violate access control, and
|
|
<tt class="literal"><span class="pre">pointee<Dereferenceable>::type&</span></tt> shall be well-formed.
|
|
Otherwise <tt class="literal"><span class="pre">iterator_traits<Dereferenceable>::reference</span></tt> shall
|
|
be well formed. [Note: These requirements need not apply to
|
|
explicit or partial specializations of <tt class="literal"><span class="pre">indirect_reference</span></tt>]</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p><tt class="literal"><span class="pre">type</span></tt> is determined according to the following algorithm, where
|
|
<tt class="literal"><span class="pre">x</span></tt> is an object of type <tt class="literal"><span class="pre">Dereferenceable</span></tt>:</p>
|
|
<pre class="literal-block">
|
|
if ( ++x is ill-formed )
|
|
return ``pointee<Dereferenceable>::type&``
|
|
else
|
|
std::iterator_traits<Dereferenceable>::reference
|
|
</pre>
|
|
</div>
|
|
<p>See proposed resolution to Issue 9.37x for more changes related to
|
|
this issue.</p>
|
|
</div>
|
|
<div class="section" id="y-n1530-typos-and-editorial-changes-in-proposal-text-not-standardese">
|
|
<h2><a class="toc-backref" href="#id47" name="y-n1530-typos-and-editorial-changes-in-proposal-text-not-standardese">9.45y N1530: Typos and editorial changes in proposal text (not standardese)</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Dave Abrahams</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<ol class="arabic">
|
|
<li><p class="first">"because specification helps to highlight that the <tt class="literal"><span class="pre">Reference</span></tt>
|
|
template parameter may not always be identical to the iterator's
|
|
<tt class="literal"><span class="pre">reference</span></tt> type, and will keep users making mistakes based on
|
|
that assumption."</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first last">add "from" before "making"</p>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</li>
|
|
<li><p class="first">mention of obsolete projection_iterator</p>
|
|
</li>
|
|
</ol>
|
|
<blockquote>
|
|
<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" colspan="2">Proposed Resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">From n1530, in the <strong>Specialized Adaptors</strong> section, remove:</p>
|
|
<blockquote class="last">
|
|
<tt class="literal"><span class="pre">projection_iterator</span></tt>, which is similar to <tt class="literal"><span class="pre">transform_iterator</span></tt>
|
|
except that when dereferenced it returns a reference instead of
|
|
a value.</blockquote>
|
|
</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Rationale:</th><td class="field-body">This iterator was in the original boost library, but the new
|
|
iterator concepts allowed this iterator to be
|
|
folded into <tt class="literal"><span class="pre">transform_iterator</span></tt>.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
</div>
|
|
<div class="section" id="y-n1530-base-return-by-value-is-costly">
|
|
<h2><a class="toc-backref" href="#id48" name="y-n1530-base-return-by-value-is-costly">9.46y N1530: <tt class="literal"><span class="pre">base()</span></tt> return-by-value is costly</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Dave Abrahams</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>We've had some real-life reports that iterators that use
|
|
<tt class="literal"><span class="pre">iterator_adaptor</span></tt>'s <tt class="literal"><span class="pre">base()</span></tt> function can be inefficient
|
|
when the <tt class="literal"><span class="pre">Base</span></tt> iterator is expensive to copy. Iterators, of
|
|
all things, should be efficient.</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">In [lib.iterator.adaptor]</p>
|
|
<p>Change:</p>
|
|
<pre class="literal-block">
|
|
Base base() const;
|
|
</pre>
|
|
<p>to:</p>
|
|
<pre class="literal-block">
|
|
Base const& base() const;
|
|
</pre>
|
|
<p class="last">twice (once in the synopsis and once in the <strong>public
|
|
operations</strong> section).</p>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="x-forgot-default-constructible-in-forward-traversal-iterator">
|
|
<h2><a class="toc-backref" href="#id49" name="x-forgot-default-constructible-in-forward-traversal-iterator">9.47x Forgot default constructible in Forward Traversal Iterator</a></h2>
|
|
<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">Submitter:</th><td class="field-body">Jeremy Siek</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>We want Forward Traversal Iterator plus Readable Lvalue Iterator to
|
|
match the old Foward Iterator requirements, so we need Forward
|
|
Traversal Iterator to include Default Constructible.</p>
|
|
<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" colspan="2">Proposed resolution:</th></tr>
|
|
<tr><td> </td><td class="field-body"><p class="first">Change:</p>
|
|
<blockquote>
|
|
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Forward Traversal Iterator</em>
|
|
concept if the following expressions are valid and respect the stated
|
|
semantics.</p>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="44%" />
|
|
<col width="39%" />
|
|
<col width="17%" />
|
|
</colgroup>
|
|
<tbody valign="top">
|
|
<tr><td colspan="3">Forward Traversal Iterator Requirements (in addition to Single Pass Iterator)</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>to:</p>
|
|
<blockquote class="last">
|
|
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Forward Traversal Iterator</em>
|
|
concept if, in addition to <tt class="literal"><span class="pre">X</span></tt> meeting the requirements of
|
|
Default Constructible and Single Pass Iterator, the following
|
|
expressions are valid and respect the
|
|
stated semantics.</p>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="38%" />
|
|
<col width="34%" />
|
|
<col width="27%" />
|
|
</colgroup>
|
|
<tbody valign="top">
|
|
<tr><td colspan="3">Forward Traversal Iterator Requirements (in addition to Default Constructible and Single Pass Iterator)</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="section" id="x-editorial-changes-non-normative-text">
|
|
<h2><a class="toc-backref" href="#id50" name="x-editorial-changes-non-normative-text">9.48x Editorial changes (non-normative text)</a></h2>
|
|
<dl>
|
|
<dt>Change:</dt>
|
|
<dd>Iterator facade uses the Curiously Recurring Template Pattern (CRTP)
|
|
[Cop95] so that the user can specify the behavior of
|
|
<tt class="literal"><span class="pre">iterator_facade</span></tt> in a derived class. Former designs used policy
|
|
objects to specify the behavior. <tt class="literal"><span class="pre">iterator_facade</span></tt> does not use policy
|
|
objects for several reasons:</dd>
|
|
<dt>to:</dt>
|
|
<dd>Iterator facade uses the Curiously Recurring Template
|
|
Pattern (CRTP) [Cop95] so that the user can specify the behavior
|
|
of <tt class="literal"><span class="pre">iterator_facade</span></tt> in a derived class. Former designs used
|
|
policy objects to specify the behavior, but that approach was
|
|
discarded for several reasons:</dd>
|
|
<dt>Change:</dt>
|
|
<dd>iterator's <tt class="literal"><span class="pre">operator++</span></tt> returns the iterator type itself means
|
|
that all iterators generated by <tt class="literal"><span class="pre">iterator_facade</span></tt> would be
|
|
instantiations of <tt class="literal"><span class="pre">iterator_facade</span></tt>. Cumbersome type generator</dd>
|
|
<dt>to:</dt>
|
|
<dd>iterator's <tt class="literal"><span class="pre">operator++</span></tt> returns the iterator type itself
|
|
would mean that all iterators built with the library would
|
|
have to be specializations of <tt class="literal"><span class="pre">iterator_facade<...></span></tt>, rather
|
|
than something more descriptive like
|
|
<tt class="literal"><span class="pre">indirect_iterator<T*></span></tt>. Cumbersome type generator</dd>
|
|
<dt>Change:</dt>
|
|
<dd>The return type for <tt class="literal"><span class="pre">operator-></span></tt> and <tt class="literal"><span class="pre">operator[]</span></tt> is not
|
|
explicitly specified. Instead it requires each <tt class="literal"><span class="pre">iterator_facade</span></tt>
|
|
instantiation to meet the requirements of its <tt class="literal"><span class="pre">iterator_category</span></tt>.</dd>
|
|
<dt>To:</dt>
|
|
<dd>The return types for <tt class="literal"><span class="pre">iterator_facade</span></tt>'s <tt class="literal"><span class="pre">operator-></span></tt> and
|
|
<tt class="literal"><span class="pre">operator[]</span></tt> are not explicitly specified. Instead, those types
|
|
are described in terms of a set of requirements, which must be
|
|
satisfied by the <tt class="literal"><span class="pre">iterator_facade</span></tt> implementation.</dd>
|
|
</dl>
|
|
</div>
|
|
<div class="section" id="x-clarification-of-iterator-facade-requirements-and-type-members">
|
|
<h2><a class="toc-backref" href="#id51" name="x-clarification-of-iterator-facade-requirements-and-type-members">9.49x Clarification of iterator_facade requirements and type members</a></h2>
|
|
<p>A general cleanup and simplification of the requirements and
|
|
description of type members for <tt class="literal"><span class="pre">iterator_facade</span></tt>.</p>
|
|
<p>The user is only allowed to add <tt class="literal"><span class="pre">const</span></tt> as a qualifier.</p>
|
|
<dl>
|
|
<dt>Change:</dt>
|
|
<dd><tt class="literal"><span class="pre">typedef</span> <span class="pre">remove_cv<Value>::type</span> <span class="pre">value_type;</span></tt></dd>
|
|
<dt>to:</dt>
|
|
<dd><tt class="literal"><span class="pre">typedef</span> <span class="pre">remove_const<Value>::type</span> <span class="pre">value_type;</span></tt></dd>
|
|
</dl>
|
|
<p>We use to have an unspecified type for <tt class="literal"><span class="pre">pointer</span></tt>, to match the
|
|
return type of <tt class="literal"><span class="pre">operator-></span></tt>, but there's no real reason to make them
|
|
match, so we just use the simpler <tt class="literal"><span class="pre">Value*</span></tt> for <tt class="literal"><span class="pre">pointer</span></tt>.</p>
|
|
<p>Change:</p>
|
|
<blockquote>
|
|
<tt class="literal"><span class="pre">typedef</span> <span class="pre">/*</span> <span class="pre">see</span> <span class="pre">description</span> <span class="pre">of</span> <span class="pre">operator-></span> <span class="pre">*/</span> <span class="pre">pointer;</span></tt></blockquote>
|
|
<dl>
|
|
<dt>To:</dt>
|
|
<dd><tt class="literal"><span class="pre">typedef</span> <span class="pre">Value*</span> <span class="pre">pointer;</span></tt></dd>
|
|
<dt>Remove:</dt>
|
|
<dd>Some of the constraints on template parameters to
|
|
<tt class="literal"><span class="pre">iterator_facade</span></tt> are expressed in terms of resulting nested
|
|
types and should be viewed in the context of their impact on
|
|
<tt class="literal"><span class="pre">iterator_traits<Derived></span></tt>.</dd>
|
|
<dt>Change:</dt>
|
|
<dd>The <tt class="literal"><span class="pre">Derived</span></tt> template parameter must be a class derived from
|
|
<tt class="literal"><span class="pre">iterator_facade</span></tt>.</dd>
|
|
<dt>and:</dt>
|
|
<dd>The following table describes the other requirements on the
|
|
<tt class="literal"><span class="pre">Derived</span></tt> parameter. Depending on the resulting iterator's
|
|
<tt class="literal"><span class="pre">iterator_category</span></tt>, a subset of the expressions listed in the table
|
|
are required to be valid. The operations in the first column must be
|
|
accessible to member functions of class <tt class="literal"><span class="pre">iterator_core_access</span></tt>.</dd>
|
|
<dt>to:</dt>
|
|
<dd>The following table describes the typical valid expressions on
|
|
<tt class="literal"><span class="pre">iterator_facade</span></tt>'s <tt class="literal"><span class="pre">Derived</span></tt> parameter, depending on the
|
|
iterator concept(s) it will model. The operations in the first
|
|
column must be made accessible to member functions of class
|
|
<tt class="literal"><span class="pre">iterator_core_access</span></tt>. In addition,
|
|
<tt class="literal"><span class="pre">static_cast<Derived*>(iterator_facade*)</span></tt> shall be well-formed.</dd>
|
|
<dt>Remove:</dt>
|
|
<dd><p class="first">The nested <tt class="literal"><span class="pre">::value_type</span></tt> type will be the same as
|
|
<tt class="literal"><span class="pre">remove_cv<Value>::type</span></tt>, so the <tt class="literal"><span class="pre">Value</span></tt> parameter must be
|
|
an (optionally <tt class="literal"><span class="pre">const</span></tt>-qualified) non-reference type.</p>
|
|
<p class="last">The nested <tt class="literal"><span class="pre">::reference</span></tt> will be the same as the <tt class="literal"><span class="pre">Reference</span></tt>
|
|
parameter; it must be a suitable reference type for the resulting
|
|
iterator. The default for the <tt class="literal"><span class="pre">Reference</span></tt> parameter is
|
|
<tt class="literal"><span class="pre">Value&</span></tt>.</p>
|
|
</dd>
|
|
</dl>
|
|
<p>Change:</p>
|
|
<blockquote>
|
|
<p>In the table below, <tt class="literal"><span class="pre">X</span></tt> is the derived iterator type, <tt class="literal"><span class="pre">a</span></tt> is an
|
|
object of type <tt class="literal"><span class="pre">X</span></tt>, <tt class="literal"><span class="pre">b</span></tt> and <tt class="literal"><span class="pre">c</span></tt> are objects of type <tt class="literal"><span class="pre">const</span> <span class="pre">X</span></tt>,
|
|
<tt class="literal"><span class="pre">n</span></tt> is an object of <tt class="literal"><span class="pre">X::difference_type</span></tt>, <tt class="literal"><span class="pre">y</span></tt> is a constant
|
|
object of a single pass iterator type interoperable with X, and <tt class="literal"><span class="pre">z</span></tt>
|
|
is a constant object of a random access traversal iterator type
|
|
interoperable with <tt class="literal"><span class="pre">X</span></tt>.</p>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="19%" />
|
|
<col width="18%" />
|
|
<col width="36%" />
|
|
<col width="26%" />
|
|
</colgroup>
|
|
<thead valign="bottom">
|
|
<tr><th>Expression</th>
|
|
<th>Return Type</th>
|
|
<th>Assertion/Note</th>
|
|
<th>Required to implement
|
|
Iterator Concept(s)</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">c.dereference()</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">X::reference</span></tt></td>
|
|
<td> </td>
|
|
<td>Readable Iterator, Writable
|
|
Iterator</td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">c.equal(b)</span></tt></td>
|
|
<td>convertible to bool</td>
|
|
<td>true iff <tt class="literal"><span class="pre">b</span></tt> and <tt class="literal"><span class="pre">c</span></tt> are
|
|
equivalent.</td>
|
|
<td>Single Pass Iterator</td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">c.equal(y)</span></tt></td>
|
|
<td>convertible to bool</td>
|
|
<td>true iff <tt class="literal"><span class="pre">c</span></tt> and <tt class="literal"><span class="pre">y</span></tt> refer to the
|
|
same position. Implements <tt class="literal"><span class="pre">c</span> <span class="pre">==</span> <span class="pre">y</span></tt>
|
|
and <tt class="literal"><span class="pre">c</span> <span class="pre">!=</span> <span class="pre">y</span></tt>.</td>
|
|
<td>Single Pass Iterator</td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">a.advance(n)</span></tt></td>
|
|
<td>unused</td>
|
|
<td> </td>
|
|
<td>Random Access Traversal
|
|
Iterator</td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">a.increment()</span></tt></td>
|
|
<td>unused</td>
|
|
<td> </td>
|
|
<td>Incrementable Iterator</td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">a.decrement()</span></tt></td>
|
|
<td>unused</td>
|
|
<td> </td>
|
|
<td>Bidirectional Traversal
|
|
Iterator</td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">c.distance_to(b)</span></tt></td>
|
|
<td>convertible to
|
|
X::difference_type</td>
|
|
<td>equivalent to <tt class="literal"><span class="pre">distance(c,</span> <span class="pre">b)</span></tt></td>
|
|
<td>Random Access Traversal
|
|
Iterator</td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">c.distance_to(z)</span></tt></td>
|
|
<td>convertible to
|
|
X::difference_type</td>
|
|
<td>equivalent to <tt class="literal"><span class="pre">distance(c,</span> <span class="pre">z)</span></tt>.
|
|
Implements <tt class="literal"><span class="pre">c</span> <span class="pre">-</span> <span class="pre">z</span></tt>, <tt class="literal"><span class="pre">c</span> <span class="pre"><</span> <span class="pre">z</span></tt>, <tt class="literal"><span class="pre">c</span>
|
|
<span class="pre"><=</span> <span class="pre">z</span></tt>, <tt class="literal"><span class="pre">c</span> <span class="pre">></span> <span class="pre">z</span></tt>, and <tt class="literal"><span class="pre">c</span> <span class="pre">>=</span> <span class="pre">c</span></tt>.</td>
|
|
<td>Random Access Traversal
|
|
Iterator</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
<p>to:</p>
|
|
<blockquote>
|
|
<p>In the table below, <tt class="literal"><span class="pre">F</span></tt> is <tt class="literal"><span class="pre">iterator_facade<X,V,C,R,D></span></tt>, <tt class="literal"><span class="pre">a</span></tt> is an
|
|
object of type <tt class="literal"><span class="pre">X</span></tt>, <tt class="literal"><span class="pre">b</span></tt> and <tt class="literal"><span class="pre">c</span></tt> are objects of type <tt class="literal"><span class="pre">const</span> <span class="pre">X</span></tt>,
|
|
<tt class="literal"><span class="pre">n</span></tt> is an object of <tt class="literal"><span class="pre">F::difference_type</span></tt>, <tt class="literal"><span class="pre">y</span></tt> is a constant
|
|
object of a single pass iterator type interoperable with <tt class="literal"><span class="pre">X</span></tt>, and <tt class="literal"><span class="pre">z</span></tt>
|
|
is a constant object of a random access traversal iterator type
|
|
interoperable with <tt class="literal"><span class="pre">X</span></tt>.</p>
|
|
<p><strong>iterator_facade Core Operations</strong></p>
|
|
<table border="1" class="table">
|
|
<colgroup>
|
|
<col width="21%" />
|
|
<col width="23%" />
|
|
<col width="27%" />
|
|
<col width="29%" />
|
|
</colgroup>
|
|
<thead valign="bottom">
|
|
<tr><th>Expression</th>
|
|
<th>Return Type</th>
|
|
<th>Assertion/Note</th>
|
|
<th>Used to implement Iterator
|
|
Concept(s)</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="literal"><span class="pre">c.dereference()</span></tt></td>
|
|
<td><tt class="literal"><span class="pre">F::reference</span></tt></td>
|
|
<td> </td>
|
|
<td>Readable Iterator, Writable
|
|
Iterator</td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">c.equal(y)</span></tt></td>
|
|
<td>convertible to bool</td>
|
|
<td>true iff <tt class="literal"><span class="pre">c</span></tt> and <tt class="literal"><span class="pre">y</span></tt>
|
|
refer to the same
|
|
position.</td>
|
|
<td>Single Pass Iterator</td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">a.increment()</span></tt></td>
|
|
<td>unused</td>
|
|
<td> </td>
|
|
<td>Incrementable Iterator</td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">a.decrement()</span></tt></td>
|
|
<td>unused</td>
|
|
<td> </td>
|
|
<td>Bidirectional Traversal
|
|
Iterator</td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">a.advance(n)</span></tt></td>
|
|
<td>unused</td>
|
|
<td> </td>
|
|
<td>Random Access Traversal
|
|
Iterator</td>
|
|
</tr>
|
|
<tr><td><tt class="literal"><span class="pre">c.distance_to(z)</span></tt></td>
|
|
<td>convertible to
|
|
<tt class="literal"><span class="pre">F::difference_type</span></tt></td>
|
|
<td>equivalent to
|
|
<tt class="literal"><span class="pre">distance(c,</span> <span class="pre">X(z))</span></tt>.</td>
|
|
<td>Random Access Traversal
|
|
Iterator</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</blockquote>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<hr class="footer" />
|
|
<div class="footer">
|
|
<a class="reference" href="iter-issue-list.rst">View document source</a>.
|
|
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
|
|
</div>
|
|
</body>
|
|
</html>
|