<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>N3066 Iterators in C++0x</title>
  <style type="text/css">
    p {text-align:justify}
    li {text-align:justify}
    ins {background-color:#FFFF99}
    del {background-color:#FF6666}
    
    tr.TITLE_ROW {text-align: center; font-weight: bold}
    tr.DELETED {background: #FF6666; text-decoration: line-through}
    tr.INSERTED {background: #FFFF99}
  </style>
  </head>
  <body>
    <address>
      Document number: N3066=10-0056<br />
      <br />
      <a href="mailto:public@alisdairm.net">Alisdair Meredith</a><br />
      2010-03-11
    </address>

    <hr />

<h1>N3066 Iterators in C++0x</h1>

<h2>Edits since previous paper</h2>
<p>
  <ul>
    <li>Simplify wording in a number of places, to avoid accidental overspecification</li>
    <li>Removed explicit return type on input iterator <tt>operator-></tt></li>
    <li>Resolve LWG #1211, move_iterator becomes a valid forward iterator or better</tt></li>
    <li>Confirmed the ability to repeatedly read from an input iterator between increments</li>
    <li>Rewrote multi-pass guarantee in terms of equivalent expressions</li>
    <li>Removed the post-increment requirement from Iterator, as stricter forms are in place for both Input Iterator and Output Iterator</li>
    <li>Removed statement that equality defines equivalence for Forward Iterators</li>
    <li>Made wording compatible with new definition of swappable proposed for Pittsburgh meeting</li>
  </ul>
</p>
<h2>Motivation for paper</h2>
<p>
While the C++ iterators and algorithms interface has proven remarkably successful,
a number of short-comings have come to light over the decade since it was designed.
Many of these were addressed by the concepts work occurring as part of the C++0x
project, and with the passing of that feature, all the work done on iterators has
been effectively lost.  This paper sets out to resolve as many of the known design
and documentation issues as possible, following the model laid out in the concepts
work.
</p>


<h2>Known Issues</h2>
<p>
There are a number of LWG issues in this area.  Those highlighted in the list 
below should change status as a result of this paper:
</p>
<table>
  <tr class="TITLE_ROW">
    <td>Number</td>
    <td>Clause</td>
    <td>Description</td>
    <td>Status (before)</td>
    <td>Status (after)</td>
  </tr>
  <tr>
    <td>408</td>
    <td>24.2 [iterator.requirements]</td>
    <td>Is vector&lt;reverse_iterator&lt;char*> > forbidden?</td>
    <td>Open</td>
    <td>NAD Editorial</td>
  </tr>
  <tr>
    <td>446</td>
    <td>24.2 [iterator.requirements]</td>
    <td>Iterator equality between different containers</td>
    <td>Open</td>
    <td>NAD Editorial</td>
  </tr>
  <tr>   
    <td>1210</td>
    <td>24.2 [iterator.requirements]</td>
    <td>iterator reachability should not require a container</td>
    <td>New</td>
    <td>NAD Editorial</td>
  </tr>
  <tr>
    <td>1212</td>
    <td>24.2 [iterator.requirements]</td>
    <td>result of post-increment/decrement operator</td>
    <td>New</td>
    <td>NAD Editorial</td>
  </tr>
  <tr>
    <td>1185</td>
    <td>24.2 [iterator.requirements]</td>
    <td>iterator categories and output iterators</td>
    <td>New</td>
    <td>NAD Editorial</td>
  </tr>
  <tr>
    <td>485</td>
    <td>24.2.2 [output.iterators]</td>
    <td>output iterator insufficiently constrained</td>
    <td>Ready</td>
    <td>NAD Editorial</td>
  </tr>
  <tr>
    <td>476</td>
    <td>24.2.3 [forward.iterators]</td>
    <td>Forward Iterator implied mutability</td>
    <td>NAD</td>
    <td>Dup 1185</td>
  </tr>
  <tr>
    <td>1311</td>
    <td>24.2.3 [forward.iterators]</td>
    <td>multi-pass property of Forward Iterator underspecified</td>
    <td>New</td>
    <td>NAD Editorial</td>
  </tr>
  <tr>
    <td>299</td>
    <td>24.2.4 [bidirectional.iterators]</td>
    <td>Incorrect return types for iterator dereference</td>
    <td>Open</td>
    <td>NAD Editorial</td>
  </tr>
  <tr>
    <td>458</td>
    <td>24.2.5 [random.access.iterators]</td>
    <td>unintended limitation for operator-</td>
    <td>NAD</td>
    <td>NAD</td>
  </tr>
  <tr>
    <td>1079</td>
    <td>24.2.5 [random.access.iterators]</td>
    <td>RandomAccessIterator's operator- has nonsensical effects clause</td>
    <td>Open</td>
    <td>NAD Editorial</td>
  </tr>
  <tr>
    <td>940</td>
    <td>24.4.4 [iterator.operations]</td>
    <td>std::distance</td>
    <td>Ready</td>
    <td>NAD Editorial</td>
  </tr>
  <tr>
    <td>1211</td>
    <td>24.5.3.1 [move.iterator]</td>
    <td>move iterators should be restricted as input iterators</td>
    <td>Open</td>
    <td>NAD Editorial</td>
  </tr>
</table>
<p>
The following issues are related to topics in this paper, but will not change
status.  They may be updated by other papers proceeding in parallel at the same
meeting.
</p>
<table>
  <tr class="TITLE_ROW">
    <td>Number</td>
    <td>Clause</td>
    <td>Description</td>
    <td>Status</td>
  </tr>
  <tr>
    <td>594</td>
    <td>20.2.1 [utility.arg.requirements]</td>
    <td>Disadvantages of defining Swappable in terms of CopyConstructible and Assignable</td>
    <td>Open</td>
  </tr>
  <tr>
    <td>742</td>
    <td>20.2.1 [utility.arg.requirements]</td>
    <td>Enabling swap for proxy iterators</td>
    <td>Open</td>
  </tr>
  <tr>
    <td>1213</td>
    <td>24.2 [iterator.requirements]</td>
    <td>Meaning of valid and singular iterator underspecified</td>
    <td>New</td>
  </tr>
</table>
<p>
Note that several of the issues marked NAD were resolved as such on the basis
that concepts would solve the problem, or remove the underlying wording.  That
is no longer the case, so we revisit those issues in this paper to see if
there should be a solution as part of the 0x wording.</p>
</p>

<h2>Motivating Examples</h2>
<p>
Here are several simple examples of types that either fail to be iterators in
unexpected ways, or appear to offer more than they can actually deliver, while
staying within the letter of the standard.
</p>

<h3>Integral Range Iterator</h3>

<pre><tt>
template&lt;unsigned M, unsigned N&gt; {
  struct iterator {
    unsigned position;

    iterator(unsigned val) : position{val} {}
    
    unsigned operator*() const { return position; }
    
    iterator& operator++() { ++position; return *this; }
    iterator& operator++(int) { return iterator{++position}; }
    
    bool operator==(iterator rhs) const { 
      return position == rhs.position;
    }
  };
  
  static iterator begin() { return iterator{M}; }
  static iterator end()   { return iterator{N}; }
};
</tt></pre>

<p>
This example is typical of a range of problematic iterators frequently referred
to as <i>proxy</i> iterators.  The key problem is that dereferencing the iterator
does not return a true native reference to the underlying element.  Examples in
the library would include the <tt>move_iterator</tt> adaptor and the well-known
<tt>vector&lt;bool&gt;::iterator</tt>.
</p>

<p>
Note that the proxy in the example is quite subtle, as it would be quite reasonable
to return a <tt>const unsigned &amp;</tt> from operator*, yet this would still be a
proxy iterator.  The reason is that each iterator is maintaining its own copy of
<tt>position</tt>, rather than sharing a reference to the same element in the
underlying sequence.  Naturally, it is difficult to share elements that exist
purely in the abstract, rather than physically in memory.  The key to this problem
is the following requirement on Forward Iterators:
</p>

<p>
"If <tt>a</tt> and <tt>b</tt> are both dereferenceable, then <tt>a == b</tt> if
and only if <tt>*a</tt> and <tt>*b</tt> are the same object."
</p>

<h3>Infinite Range</h3>
<p>
The following constant iterator allows iteration over an infinite sequence of
values.
</p>

<pre><tt>
template&lt;unsigned N&gt; {
  struct iterator {
    static const unsigned value = N;

    iterator() {}
    
    const unsigned & operator*() const { return value; }
    
    iterator& operator++() { return *this; }
    iterator& operator++(int) { return *this; }
    
    bool operator==(iterator rhs) const { 
      return true;
    }
  };
  
</tt></pre>

<p>
Note that this iterator seems fine at first, and does not suffer the proxy
issue as all references truly refer to the same object.  However, it has the
unusual property that the distance between any two iterators is zero.  This will
be very surprising for consumers of Forward Iterators and the more capable
categories, yet there is nothing restricting this to a mere Input Iterator.
</p>
<p>
Note that it would be very simple to add support for a distance property to this
iterator by adding an additional <tt>size_t</tt> member to track position.  It
would seem a stretch to describe such a range as truly infinite though, if the
maximum expressible distance is distinctly finite.
</p>

<h3>A Single-pass Forward Iterator</h3>
<p>
Consider the following iterator adaptor:
</p>
<pre><tt>
template&lt;typename Iter&gt; 
struct shared_iterator {
  shared_ptr<Iter> position;

  shared_iterator(Iter val) : position{new Iter{val}} {}
  
  unsigned operator*() const { return *position; }
  
  shared_iterator& operator++() { ++*position; return *this; }
  shared_iterator operator++(int) { 
    shared_iterator result{*this};
    ++*iterator;
    return result;
  }
  
  bool operator==(const shared_iterator& rhs) const { 
    return *position == *rhs.position;
  }
};
</tt></pre>

<p>
This example subverts the notion that a Forward Iterator is a multi-pass iterator
by simply wrapping any other iterator in a <tt>shared_ptr</tt>, and deferring all operations
to the shared iterator.  All copies of this iterator share the same underlying
base iterator, so incrementing any one will increment them all.  Yet this adaptor
still meets all the requirements of a conforming Forward Iterator.  While iterating
the underlying sequence is consumed, but all copied iterators reach the end at
the same time, and will continue to behave correctly as past-the-end iterators
at that point.  This is the basis of LWG issue 1311.
</p>



<h2>Other issues</h2>

<h3>Inconsistent Style</h3>
<p>
One of the features of the 0x standardization process in the library clauses has
been an improved consistency of wording and style.  There is less duplication,
as common terms are defined in a single place, typically the Requirement section
of clause 20, and then referenced as needed.  The iterators clause relied on
concepts to provide the same consistency, so the wording has not benefitted from
the same attention to detail.  The effects are more noticeable as the core
language grows, delivering an increasingly diverse range of syntax to effect the
same expression.
</p>


<h3>Shuffle Iterators</h3>
<p>
One of the key discoveries of the concepts work was a new iterator concept
dubbed the <i>Shuffle Iterator</i>.  This combined many of the features of a
mutable Forward Iterator with the <tt>Swappable</tt> concept in order to
better describe the requirements on algorithms in clause 25.</p>
<p>
It is not clear that the requirements for a Shuffle Iterator can be so easily
expressed without the language of concepts, so this paper makes no attempt to
add Shuffle Iterators into the standard taxonomy of iterators.
</p>



<h2>Proposed Solutions</h2>
<p>
The goal of this paper is in many ways to be evolutionary, not revolutionary.
Rather than immediately solving all the possible problems, the goal is to
update the wording of this clause to a level consistent with the rest of the
working paper, and consistent with the lessons from concepts.  This clarified
wording will form a strong basis for future papers or issues to address specific
concerns
</p>

<h3>Reference Types</h3>
<p>
It is generally thought that the biggest problem facing iterator consumers is
the poorly defined support for proxied iterators.  This paper starts to address
that by naming the reference type returned by an iterator's <tt>operator*</tt>.
This is transparently made possible by extending <tt>iterator_traits</tt> with a
new type alias using the new <tt>decltype</tt> keyword.  This automatically
supports pointers and all existing iterators with an appropriate default, and
could be opened up as an extension point in the future, once clear requirements
on the reference type have been defined.  We choose to go no further on this
issue at the moment, waiting on clarification of the wording for <tt>Swappable</tt>
types among other issues.
</p>

<h3>Re-use Common Definitions</h3>
<p>
There are many useful terms defined in clause 20.2 [Requirements] that can
simplify the presentation of the iterator requirements.  This happened by default
in the concept-based version of the library.  The benefit is clear, as many of
these terms have been tweaked with a considerable attention to detail in the
currently proposed standard.  The requirements clauses and tables for each
iterator category are adjusted accordingly.
</p>

<h3>Constant Iterators can be Random Access Iterators</h3>
<p>
LWG 476 points out that it is very easy to read into the current wording the
requirement that all Forward, Bidirectional and Random Access Iterators must
also be Output Iterators.  Hence, <tt>std::vector&lt;T&gt;::const_iterator</tt>
is merely an Input Iterator.  This was much clearer in the concpets version of
the clause, so that wording is adopted here.
</p>



<h2>Wording</h2>

<h4>24.2 Iterator requirements [iterator.requirements]</h4>
<p>
1 Iterators are a generalization of pointers that allow a C++ program to work with different data structures
(containers) in a uniform manner. To be able to construct template algorithms that work correctly and
efficiently on different types of data structures, the library formalizes not just the interfaces but also the
semantics and complexity assumptions of iterators. All input iterators i support the expression *i, resulting
in a value of some class, enumeration, or built-in type <tt>T</tt>, called the <i>value type</i> of the iterator. All output
iterators support the expression <tt>*i = o</tt> where o is a value of some type that is in the set of types that are
<i>writable</i> to the particular iterator type of <tt>i</tt>. All iterators <tt>i</tt> for which the expression <tt>(*i).m</tt> is well-defined,
support the expression <tt>i->m</tt> with the same semantics as <tt>(*i).m</tt>. For every iterator type <tt>X</tt> for which equality
is defined, there is a corresponding signed integral type called the <i>difference type</i> of the iterator.
</p>
<p>
2 Since iterators are an abstraction of pointers, their semantics is a generalization of most of the semantics
of pointers in C++. This ensures that every function template that takes iterators works as well with
regular pointers. This International Standard defines five categories of iterators, according to the operations
defined on them: input iterators, output iterators, forward iterators, bidirectional iterators and random access
iterators, as shown in Table 100.
Table 100 — Relations among iterator categories
Random Access ! Bidirectional ! Forward ! Input
! Output
</p>
<p>
3 Forward iterators satisfy all the requirements of <del>the</del> input <del>and output</del> iterators and can be used whenever
<del>either kind</del><ins>an input iterator</ins> is specified; Bidirectional iterators also satisfy all the requirements of <del>the</del> forward iterators and
can be used whenever a forward iterator is specified; Random access iterators also satisfy all the requirements
of bidirectional iterators and can be used whenever a bidirectional iterator is specified.
</p>
<p>
<del>4 Besides its category, a forward, bidirectional, or random access iterator can also be mutable or constant
depending on whether the result of the expression *i behaves as a reference or as a reference to a constant.
Constant iterators do not satisfy the requirements for output iterators, and the result of the expression *i
(for constant iterator i) cannot be used in an expression where an lvalue is required.</del>
</p>
<p>
<ins>4 Iterators that further satisy all the requirements of output iterators are called <i>mutable iterators</i>. Nonmutable
iterators are referred to as <i>constant iterators</i>.</ins>
</p>
<p>
5 Just as a regular pointer to an array guarantees that there is a pointer value pointing past the last element of
the array, so for any iterator type there is an iterator value that points past the last element of a corresponding
sequence. These values are called past-the-end values. Values of an iterator i for which the expression *i is
defined are called dereferenceable. The library never assumes that past-the-end values are dereferenceable.
Iterators can also have singular values that are not associated with any <del>container</del><ins>sequence</ins>. [ Example: After the
declaration of an uninitialized pointer x (as with int* x;), x must always be assumed to have a singular
value of a pointer. —end example ] Results of most expressions are undefined for singular values; the only
exceptions are destroying an iterator that holds a singular value <del>and</del><ins>,</ins> the assignment of a non-singular value
to an iterator that holds a singular value<ins>, and, for iterators that satisfy the DefaultConstructible
requirements, using a value-initialized iterator as the source of a copy or
move operation. [Note: this guarantee is not offered for
default-initialization, although the distinction only matters for types with
trivial default contructors, such as pointers or 
aggregates holding pointers.— end note]</ins>. In this case the singular value is overwritten the same way as any
other value. Dereferenceable values are always non-singular.
</p>

<p>
6 An iterator <tt>j</tt> is called <i>reachable</i> from an iterator <tt>i</tt> if and only if there is a finite sequence of applications of
the expression <tt>++i</tt> that makes <tt>i == j</tt>. If <tt>j</tt> is reachable from <tt>i</tt>, they refer to elements of the same sequence.
</p>
<p>
7 Most of the library's algorithmic templates that operate on data structures have interfaces that use ranges.
A <i>range</i> is a pair of iterators that designate the beginning and end of the computation. A range <tt>[i,i)</tt> is
an empty range; in general, a range <tt>[i,j)</tt> refers to the elements in the data structure starting with the <del>one</del><ins>element</ins>
pointed to by <tt>i</tt> and up to but not including the <del>one</del><ins>element</ins> pointed to by <tt>j</tt>. Range <tt>[i,j)</tt> is valid if and only if <tt>j</tt>
is reachable from <tt>i</tt>. The result of the application of functions in the library to invalid ranges is undefined.
</p>
<p>
8 All the categories of iterators require only those functions that are realizable for a given category in constant
time (amortized). Therefore, requirement tables for the iterators do not have a complexity column.
</p>
<p>
9 Destruction of an iterator may invalidate pointers and references previously obtained from that iterator.
</p>
<p>
10 An <i>invalid</i> iterator is an iterator that may be singular.267
</p>
<p>
11 In the following sections, <tt>a</tt> and <tt>b</tt> denote values of type 
   <tt>X</tt> or <tt>const X</tt>, <ins><tt>difference_type</tt> and 
   <tt>reference</tt> refer to the types <tt>iterator_traits&lt;X>::difference_type</tt>
   and <tt>iterator_traits&lt;X>::reference</tt> respectively,</ins> <tt>n</tt>
   denotes a value of <del>the difference type <tt>Distance</del>
   <ins>difference_type</ins></tt>, <tt>u</tt>, <tt>tmp</tt>, and <tt>m</tt> 
   denote identifiers, <tt>r</tt> denotes a value of <tt>X&amp;</tt>, <tt>t</tt> denotes a value of
   <del>value</del> type <tt>T</tt>, <tt>o</tt> denotes a value of some type
   that is writable to the output iterator. <ins>[<i>Note:</i>
   for an iterator type <tt>X</tt> there must be an instantiation of
   <tt>iterator_traits&lt;X></tt> (24.4.1 [iterator.traits]) - end note]</ins>
</p>

<p>
267) This definition applies to pointers, since pointers are iterators. The effect of dereferencing an iterator that has been
invalidated is undefined.
</p>

<ins>
<h4>24.2.1 Iterator [iterator.iterators]</h4>
<p>
1 The <tt>Iterator</tt> requirements form the basis of the iterator concept
  taxonomy, and every iterator meets the <tt>Iterator</tt> requirements. This 
  set of requirements specifies operations for dereferencing and incrementing
  the iterator. Most algorithms will
  require additional operations to read ([input.iterators]) or write 
  ([output.iterators]) values, or to provide a richer set of iterator movements 
  ([forward.iterators],[birectional.iterators], [random.access.iterators]).
</p>
<p>
2 A type <tt>X</tt> conforms to the <tt>Iterator</tt> requirements if:
  <li>
    <tt>X</tt> satisfies the <tt>CopyConstructible</tt>,
    <tt>CopyAssignable</tt>, and <tt>Destructible</tt> requirements
    ([utility.arg.requirements]) and lvalue of type <tt>X</tt> are swappable([swappable.requirements]).
  </li>
  <li>The expressions shown in Table ?? Iterator Requirements are valid and have the indicated semantics</li>
</p>

  <table cellspacing="0" cellpadding="0" border="0">
    <caption>Table ?? - Iterator requirements</caption>

    <tr class="TITLE_ROW">
      <td>Expression</td>
      <td>Return type</td>
      <td>Operational semantics</td>
      <td>Assertion/note/ pre-/post-condition</td>
    </tr>

    <tr>
      <td><tt>*r</tt></td>
      <td><tt>reference</tt></td>
      <td></td>
      <td>pre: <tt>r</tt> is dereferenceable.</td>
    </tr>
    
    <tr>
      <td><tt>++r</tt></td>
      <td><tt>X&amp;</tt></td>
      <td></td>
      <td></td>
    </tr>
  </table>
</ins>


<h4>24.2.<del>1</del><ins>2</ins> Input iterators [input.iterators]</h4>
<p>
1 A class or a built-in type <tt>X</tt> satisfies the requirements of an input
 iterator for the value type <tt>T</tt> if <ins> <tt>X</tt> satisfies the
 <tt>Iterator</tt> (24.2.1) and <tt>EqualityComparable</tt> (20.2) requirements
 , and </ins> the following expressions are valid, as shown in Table 101.
</p>
<p>
2 In Table 101, the term the domain of == is used in the ordinary mathematical sense to denote the set of
values over which == is (required to be) defined. This set can change over time. Each algorithm places
additional requirements on the domain of == for the iterator values it uses. These requirements can be
inferred from the uses that algorithm makes of == and !=. [ Example: the call find(a,b,x) is defined only
if the value of a has the property p defined as follows: b has property p and a value i has property p if
(*i==x) or if (*i!=x and ++i has property p). —end example ]
</p>
  <table cellspacing="1">
    <caption>Table 101 - Input iterator requirements <ins>(in addition to iterator)</ins></caption>
    <tr class="TITLE_ROW">
      <td><del>Operation</del><ins>Expression</ins></td>
      <td><ins>Return</ins> Type</td>
      <td><ins>Operational semantics</ins></td>
      <td><del>Semantics,</del><ins>Assertion/note/ </ins> pre-/post-conditions</td>
    </tr>

    <tr class="DELETED">
      <td><tt>X u(a);</tt></td>
      <td><tt>X</tt></td>
      <td></td>
      <td>
        post: <tt>u</tt> is a copy of <tt>a</tt><br />
        A destructor is assumed to be present and accessible.</td>
    </tr>

    <tr class="DELETED">
      <td>u = a;</td>
      <td>X&amp;</td>
      <td></td>
      <td>result: <tt>u</tt><br />
          post: <tt>u</tt> is a copy of <tt>a</tt></td>
    </tr>

    <tr class="DELETED">
      <td><tt>a == b</tt></td>
      <td>convertible to <tt>bool</tt></td>
      <td></td>
      <td><tt>==</tt> is an equivalence relation over its domain.</td>
    </tr>

    <tr>
      <td><tt>a != b</tt></td>
      <td><ins>contextually</ins> convertible to bool</td>
      <td>
        <ins><tt>!(a == b)</tt></ins>
      </td>
      <td>
        <ins>pre: <tt>(a,b)</tt> is in the domain of <tt>==</tt>.</ins><br />
        <del><tt>bool(a == b) != bool(a != b)</tt> over the domain of <tt>==</tt></del><br />
      </td>
    </tr>

    <tr>
      <td><tt>*a</tt></td>
      <td>convertible to <tt>T</tt></td>
      <td></td>
      <td>
        pre: <tt>a</tt> is dereferenceable.<br />
        <ins><tt>(void)*a,*a</tt> is equivalent to <tt>*a</tt>.</ins><br />
        If <tt>a == b</tt> and <tt>(a,b)</tt> is in the domain of <tt>==</tt> 
        then <tt>*a</tt> is equivalent to <tt>*b</tt>.</td>
    </tr>

    <tr>
      <td><tt>a->m</tt></td>
      <td></td>
      <td><ins><tt>(*a).m</tt></ins></td>
      <td>
        <ins>pre: <tt>a</tt> is dereferenceable.</ins><br />
        <del>pre: <tt>(*a).m</tt> is well-defined.<br /></del>
        <del>Equivalent to <tt>(*a).m</tt>.</del></td>
    </tr>

    <tr>
      <td><tt>++r</tt></td>
      <td><tt>X&amp;</tt></td>
      <td></td>
      <td>
        pre: <tt>r</tt> is dereferenceable.<br />
        post: <tt>r</tt> is dereferenceable or <tt>r</tt> is past-the-end.<br />
        post: any copies of the previous value of <tt>r</tt> are no longer required
              either to be dereferenceable or to be in the domain of <tt>==</tt>.
      </td>
    </tr>

    <tr>
      <td><tt>(void)r++</tt></td>
      <td></td>
      <td></td>
      <td>equivalent to <tt>(void)++r</tt></td>
    </tr>

    <tr>
      <td><tt>*r++</tt></td>
      <td>convertible to <tt>T</tt></td>
      <td><ins><tt>{ T tmp = *r; ++r; return tmp; }</tt></ins></td>
      <td><del><tt>{ T tmp = *r; ++r; return tmp; }</tt></del></td>
    </tr>
  </table>

<p>
3 [ Note: For input iterators, <tt>a == b</tt> does not imply <tt>++a == ++b</tt>.
  (Equality does not guarantee the substitution property or referential transparency.)
  Algorithms on input iterators should never attempt to pass through the same
  iterator twice. They should be single pass algorithms. Value type <tt>T</tt> is
  not required to be a<del>n</del> <tt><ins>Copy</ins>Assignable</tt> type 
  (2<del>3</del><ins>0</ins>.2). These algorithms can be used with <tt>istream</tt>s 
  as the source of the input data through the <tt>istream_iterator</tt> class 
  template. —end note ]
</p>


<h4>24.2.<del>2</del><ins>3</ins> Output iterators [output.iterators]</h4>
<p>
1 A class or a built-in type <tt>X</tt> satisfies the requirements of an output
 iterator if <tt>X</tt> <del>is a <tt>CopyConstructible</tt> (34) and 
 <tt>Assignable</tt></del><ins>satisfies the 
 <tt>Iterator</tt> requirements</ins> <del>type</del> (23.2) and also the following expressions 
 are valid, as shown in Table 102.
</p>
  <table cellspacing="1">
    <caption>Table 102 — Output iterator requirements <ins>(in addition to iterator)</ins></caption>

    <tr class="TITLE_ROW">
      <td>Expression</td>
      <td>Return type</td>
      <td>Operational semantics</td>
      <td>Assertion/note/ pre-/post-condition</td>
    </tr>

    <tr class="DELETED">
      <td><tt>X(a)</tt></td>
      <td></td>
      <td></td>
      <td><tt>a = t</tt> is equivalent to <tt>X(a) = t</tt>.<br />
          note: a destructor is assumed.</td>
    </tr>
    
    <tr class="DELETED">
      <td><tt>X u(a);</tt></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr class="DELETED">
      <td><tt>X u = a;</tt></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    
    <tr>
      <td><tt>*r = o</tt></td>
      <td>result is not used</td>
      <td></td>
      <td>
        <ins>post: <tt>r</tt> is not required to be dereferenceable.<br/>
        post: <tt>r</tt> is incrementable.</ins>
      </td>
    </tr>
    
    <tr>
      <td><tt>++r</tt></td>
      <td><tt>X&amp;</tt></td>
      <td></td>
      <td>
        <tt>&amp;r == &amp;++r</tt>.<br />
        <ins>post: <tt>r</tt> is dereferenceable, unless otherwise specified.<br />
        post: <tt>r</tt> is not required to be incrementable.</ins>
      </td>
    </tr>
    
    <tr>
      <td><tt>r++</tt></td>
      <td>convertible to <tt>const X&amp;</tt></td>
      <td><tt>{ X tmp = r; ++r; return tmp; }</tt></td>
      <td>
        <ins>post: <tt>r</tt> is dereferenceable, unless otherwise specified.<br />
        post: <tt>r</tt> is not required to be incrementable.</ins>
      </td>
    </tr>
    
    <tr>
      <td><tt>*r++ = o</tt></td>
      <td>result is not used</td>
      <td></td>
      <td>
        <ins>post: <tt>r</tt> is dereferenceable, unless otherwise specified.<br />
        post: <tt>r</tt> is not required to be incrementable.</ins>
      </td>
    </tr>
    
  </table>

<p>
2 [ Note: The only valid use of an operator* is on the left side of the assignment statement. Assignment
through the same value of the iterator happens only once. Algorithms on output iterators should never
attempt to pass through the same iterator twice. They should be single pass algorithms. Equality and
inequality might not be defined. Algorithms that take output iterators can be used with ostreams as the
destination for placing data through the ostream_iterator class as well as with insert iterators and insert
pointers. —end note ]
</p>


<h4>24.2.<del>3</del><ins>4</ins> Forward iterators [forward.iterators]</h4>
<p>
1 A class or a built-in type <tt>X</tt> satisfies the requirements of a forward
  iterator if <del> the following expressions are valid, as shown in Table 103.</del><ins>:
<li><tt>X</tt> satisfies all the requirements of an input iterator</li>
<li>
  <tt>X</tt> satisfies the <tt>DefaultConstructible</tt> requirements ([utility.arg.requirements])
</li>
<li>
  If <tt>X</tt> is a mutable iterator, <tt>reference</tt> is a reference to <tt>T</tt>.
  If <tt>X</tt> is a constant iterator, <tt>reference</tt> is a reference to <tt>const T</tt>.
</li>
<li>The expressions shown in Table 103 are valid, and have the described semantics.</li>
<li>Objects of type <tt>X</tt> offer the multi-pass guarantee below.</li>
</ins></p>
<p><ins>
  The domain of <tt>==</tt> for forward iterators is that of iterators over the
  same underlying sequence.
</ins></p>

<p><ins>
Two dereferenceable iterators <tt>a</tt> and <tt>b</tt> of type <tt>X</tt> deliver
the multi-pass guarantee if:
<ul>
  <li><tt>a == b</tt> implies <tt>++a == ++b</tt></li>
  <li>
    The expression <tt>(void)++X(a),*a</tt> is equivalent to the expression 
    <tt>*a</tt>, or <tt>X</tt> is a pointer type
  </li>
</ul>
</ins></p>

  <table cellspacing="1">
    <caption>Table 103 — Forward iterator requirements <ins>(in addition to input iterator)</ins></caption>

    <tr class="TITLE_ROW">
      <td>Expression</td>
      <td>Return type</td>
      <td>Operational semantics</td>
      <td>Assertion/note/ pre-/post-condition</td>
    </tr>

    <tr class="DELETED">
      <td><tt>X u;</tt></td>
      <td></td>
      <td></td>
      <td> note: <tt>u</tt> might have a singular value.<br />
           note: a destructor is assumed.</td>
    </tr>

    <tr class="DELETED">
      <td><tt>X()</tt></td>
      <td></td>
      <td></td>
      <td>note: <tt>X()</tt> might be singular.</td>
    </tr>
    
    <tr class="DELETED">
      <td><tt>X(a)</tt></td>
      <td></td>
      <td></td>
      <td><tt>a == X(a)</tt></td>
    </tr>

    <tr class="DELETED">
      <td>
        <tt>X u(a);</tt><br />
        <tt>X u = a;</tt>
      </td>
      <td></td>
      <td><tt>X u; u = a;</tt></td>
      <td>post: <tt>u == a</tt></td>
    </tr>

    <tr class="DELETED">
      <td><tt>a == b</tt></td>
      <td>convertible to <tt>bool</tt></td>
      <td></td>
      <td><tt>==</tt> is an equivalence relation.</td>
    </tr>

    <tr class="DELETED">
      <td><tt>a != b</tt></td>
      <td>convertible to <tt>bool</tt></td>
      <td><tt>!(a == b)</tt></td>
      <td></td>
    </tr>
    
    <tr class="DELETED">
      <td><tt>r = a</tt></td>
      <td><tt>X&amp;</tt></td>
      <td></td>
      <td>post: <tt>r == a</tt></td>
    </tr>

    <tr class="DELETED">
      <td><tt>*a</tt></td>
      <td>
        <tt>T&amp;</tt> if <tt>X</tt> is mutable,<br />
        otherwise <tt>const T&amp;</tt>
      </td>
      <td></td>
      <td>
        pre: <tt>a</tt> is dereferenceable.<br />
        <tt>a == b implies <tt>*a == *b</tt>.<br />
        If <tt>X</tt> is mutable, <tt>*a = t</tt> is valid.
      </td>
    </tr>

    <tr class="DELETED">
      <td><tt>a->m</tt></td>
      <td>
        <tt>U&amp;</tt> if <tt>X</tt> is mutable,<br />
        otherwise <tt>const U&amp;</tt>
      </td>
      <td><tt>(*a).m</tt></td>
      <td>pre: <tt>(*a).m</tt> is well-defined.</td>
    </tr>
    
    <tr class="DELETED">
      <td><tt>++r</tt></td>
      <td><tt>X&amp;</tt></td>
      <td></td>
      <td>
        pre: <tt>r</tt> is dereferenceable.<br />
        post: <tt>r</tt> is dereferenceable or <tt>r</tt> is past-the-end.<br />
        <tt>r == s</tt> and r is dereferenceable implies <tt>++r == ++s</tt>.<br />
        <tt>&amp;r == &amp;++r</tt>.
      </td>
    </tr>

    <tr>
      <td><tt>r++</tt></td>
      <td>convertible to <tt>const X&amp;</tt></td>
      <td><tt>{ X tmp = r; ++r; return tmp; }</tt></td>
      <td></td>
    </tr>
    
    <tr>
      <td><tt>*r++</tt></td>
      <td>
        <del><tt>T&amp;</tt> if <tt>X</tt> is mutable, otherwise <tt>const T&amp;</tt></del><br />
        <ins><tt>reference</tt></ins>
      </td>
      <td></td>
      <td></td>
    </tr>
    
  </table>

<p>
— If <tt>a</tt> and <tt>b</tt> are equal, then either <tt>a</tt> and <tt>b</tt>
are both dereferenceable or else neither is dereferenceable.<br />
— If <tt>a</tt> and <tt>b</tt> are both dereferenceable, then <tt>a == b</tt>
if and only if <tt>*a</tt> and <tt>*b</tt> are <ins>bound to</ins> the same object.
</p>
<p>
2 [ Note: The <del>condition</del><ins>requirement</ins> that <tt>a == b</tt>
implies </tt>++a == ++b</tt> (which is not true for input and output iterators)
and the removal of the restrictions on the number of the assignments through 
<del>the</del><ins>a mutable</ins> iterator (which applies to output iterators)
allows the use of multi-pass one-directional algorithms with forward iterators.
—end note ]
</p>


<h4>24.2.<del>4</del><ins>5</ins> Bidirectional iterators [bidirectional.iterators]</h4>
<p>
1 A class or a built-in type X satisfies the requirements of a bidirectional iterator if, in addition to satisfying
the requirements for forward iterators, the following expressions are valid as shown in Table 104.
</p>
    <table cellspacing="1">
    <caption>Table 104 — Bidirectional iterator requirements (in addition to forward iterator)</caption>

    <tr class="TITLE_ROW">
      <td>Expression</td>
      <td>Return type</td>
      <td>Operational semantics</td>
      <td>Assertion/note/ pre-/post-condition</td>
    </tr>

    <tr>
      <td><tt>--r</tt></td>
      <td><tt>X&amp;</tt></td>
      <td></td>
      <td>
        pre: there exists <tt>s</tt> such that <tt>r == ++s</tt>.<br />
        post: <tt>r</tt> is dereferenceable.<br />
        <tt>--(++r) == r</tt>.<br />
        <tt>--r == --s</tt> implies <tt>r == s</tt>.<br />
        <tt>&amp;r == &amp;--r</tt>.
      </td>
    </tr>
      
    <tr>
      <td><tt>r--</tt></td>
      <td>convertible to <tt>const X&amp;</tt></td>
      <td><tt>{ X tmp = r; --r; return tmp; }</tt></td>
      <td></td>
    </tr>
    
    <tr>
      <td><tt>*r--</tt></td>
      <td>
        <del>convertible to <tt>T</tt></del><br />
        <ins><tt>reference</tt></ins>
      </td>
      <td></td>
      <td></td>
    </tr>
    
    </table>
    
<p>
2 [ Note: Bidirectional iterators allow algorithms to move iterators backward as well as forward. —end note ]
</p>


<h4>24.2.<del>5</del><ins>6</ins> Random access iterators [random.access.iterators]</h4>
<p>
1 A class or a built-in type <tt>X</tt> satisfies the requirements of a random 
  access iterator if, in addition to satisfying the requirements for bidirectional
  iterators, the following expressions are valid as shown in Table 105.
</p>

  <table cellspacing="0" cellpadding="0" border="0">
    <caption>Table 105 — Random access iterator requirements (in addition to bidirectional iterator)</caption>

    <tr class="TITLE_ROW">
      <td>Expression</td>
      <td>Return type</td>
      <td>Operational semantics</td>
      <td>Assertion/note/ pre-/post-condition</td>
    </tr>
    
    <tr>
      <td><tt>r += n</tt></td>
      <td><tt>X&amp;</tt></td>
      <td>
<pre><tt>
{ <del>Distance</del><ins>difference_type</ins> m = n;
  if (m >= 0)
    while (m--)
      ++r;
    else while (m++)
      --r;
  return r; }
</tt></pre></td>
      <td></td>
    </tr>

    <tr>
      <td><tt>
        a + n<br />
        n + a</tt>
      </td>
      <td><tt>X</tt></td>
      <td><tt>{ X tmp = a; return tmp += n; }</tt></td>
      <td><tt>a + n == n + a</tt>.</td>
    </tr>
    
    <tr>
      <td><tt>r -= n</tt></td>
      <td><tt>X&amp;</tt></td>
      <td><tt>return r += -n;</tt></td>
      <td></td>
    </tr>
    
    <tr>
      <td><tt>a - n</tt></td>
      <td><tt>X</tt></td>
      <td><tt>{ X tmp = a; return tmp -= n; }</tt></td>
      <td></td>
    </tr>
    
    <tr>
      <td><tt>b - a</tt></td>
      <td><tt><del>Distance</del><ins>difference_type</ins></tt></td>
      <td>
        <del><tt>(a &lt; b) ? distance(a,b) : -distance(b,a)</tt></del><br />
        <ins><tt>return n;</tt></ins>
      </td>
      <td>
        pre: there exists a value <tt>n</tt> of <tt><del>Distance</del><ins>difference_type</ins></tt>
             such that <tt>a + n == b</tt>.<br />
        <tt>b == a + (b - a)</tt>.
      </td>
    </tr>

    <tr>
      <td><tt>a[n]</tt></td>
      <td>convertible to <tt><del>const T &amp;</del><ins>reference</ins></tt></td>
      <td><tt>*(a + n)</tt></td>
      <td></td>
    </tr>
    
    <tr>
      <td><tt>a &lt; b</tt></td>
      <td><ins>contextually</ins> convertible to <tt>bool</tt></td>
      <td><tt>b - a > 0</tt></td>
      <td><tt>&lt;</tt> is a total ordering relation</td>
    </tr>
    
    <tr>
      <td><tt>a &gt; b</tt></td>
      <td><ins>contextually</ins> convertible to <tt>bool</tt></td>
      <td><tt>b &lt; a</tt></td>
      <td><tt>></tt> is a total ordering relation opposite to <tt>&lt;</tt>.</td>
    </tr>
    
    <tr>
      <td><tt>a &gt;= b</tt></td>
      <td><ins>contextually</ins> convertible to <tt>bool</tt></td>
      <td><tt>!(a &lt; b)</tt></td>
      <td></td>
    </tr>
    
    <tr>
      <td><tt>a &lt;= b</tt></td>
      <td><ins>contextually</ins> convertible to <tt>bool</tt></td>
      <td><tt>!(a &gt; b)</tt></td>
      <td></td>
    </tr>
    
  </table>
  
<h2>Synchronization</h2>
<p>
In order to remain compatible with Ready issues currently going being handled 
by regular issues list processing, the following changes should also be made:
</p>

<h3>Issue 940</h3>
<p>
Change 24.4.4 [iterator.operations]/4+5 as indicated:
</p> 

<pre><tt>
template&lt;class InputIterator&gt;
  typename iterator_traits&lt;InputIterator>::difference_type
    distance(InputIterator first, InputIterator last);
</tt></pre>
<p>
4 Effects: <ins>If <tt>InputIterator</tt> meets the requirements of random access iterator then 
           returns <tt>(last - first)</tt>, otherwise r</ins><del>R</del>eturns the number of
           increments <del>or decrements</del> needed to get from <tt>first</tt> to <tt>last</tt>.
</p>
<p>
5 Requires: <ins>If <tt>InputIterator</tt> meets the requirements of random access iterator
            then <tt>last</tt> shall be reachable from <tt>first</tt> or <tt>first</tt> shall be reachable
            from <tt>last</tt>, otherwise</ins> <tt>last</tt> shall be reachable from <tt>first</tt>. 
</p>

<h1>Aknowledgements</h1>
I would particularly like to thank Dave Abrahams and Matt Austern.  This paper
is significantly improved as a consequence of their reviews.  Any remaining
errors are, of course, all my own.
</body>
</html>