Topic: C++0x (iterators)


Author: Michael Lee Finney <michael.finney@acm.org>
Date: Tue, 15 May 2001 05:04:50 GMT
Raw View
There has been some discussion of sequences vs.
iterators. One major problem that I have with
iterators as defined in the STL is that everything is
done via xxx.begin() to xxx.end() where both represent
an iterator and items are typically processed from
xxx.begin() to, but not including, xxx.end().

The problem is that it is very natural to use
iterators to model many, many things. Some of which
are infinite (or at least unbounded) sequences. So,
there is no xxx.end() possible, and sometimes there is
no xxx.begin() possible.

I created the following definition of an iterator,
which is what I use for modelling sequences. I find
that it works extremely well and I have represented
many different things as iterators. Not just elements
of a list, but also all sorts of random sequences,
buffer accessing, permutations. Basically, anywhere I
can create code that constructs items one at a time
and where I want to see a sequence of those items is
possible. This definition has evolved over a number of
years and it seems to represent things fairly well.

In practice, the lack of infinite numbers requires
various constraints -- positions may exist as separate
objects but it may not always be possible to take the
difference of a position. A position may or may not be
represents by an integer.

Examples of using this approach are...

  for (Iterator I; not I.atUpperBound(); ++I)

or, where a sentential value is defined...

  for (Iterator I; *I != sentential; ++I)

which can sometimes be substantially faster. It is
always possible to convert STL iterators to this form
by defining atUpperBound() as

   bool atUpperBound() const
      {
      return *this == end();
      }

where the expression is to be taken as an idea and not
as working code.

Anyway, the formalism is...

====================================================

   An iterator is formally defined as a tuple...

      <L,U,I,P,r,p,O,M,m,A,X,R,D>

   where...

      L  is the greatest lower bound of the iterator.
         If the iterator is infinite to the left, L
         is the first negative transfinite ordinal
         -N (aleph).

      U  is the least upper bound of the iterator.
         If the iterator is infinite to the right, U
         is the first positive transfinite ordinal
         N (aleph).

      I  is the open interval (L,U) over integers.
         I is called the indexing set of the iterator.
         Notice that I contains neither the greatest
         lower bound nor the least upper bound.

      P  is the open interval (L-1,U+1) over integers.
         If L and U are, respectively, -N and N then
         P = I (see note below). The elements of P
         are called the positions of the iterator.

         Note: It is assumed that we are working in
               a number system which contains the
               negative integers, zero, positive
               integers following the usual rules of
               arithmetic and which has been extended
               with the first negative transfinite
               ordinal (-N) and the first positive
               transfinite ordinal (N) such that:

                  N + n = n + N = N
                  N + N = N
                  n + -N = -N + n = -N
                 -N + -N = -N
                  N + -N = -N + N = 0

               where n is any finite integer, and
               where n + -m is to be considered the
               same as n - m in the usual manner. In
               other words, N and -N are "sticky".
               Similar rules follow for multiplication
               and division.

      r  is an element of P and is called the initial
         position.

      p  is an element of P and is called the
         distinguished position. Immediately following
         creation of the iterator and immediately
         after the iterator has been reset, p = r.

      O  is a set of objects.

      M  is the set of positions at which m is
         defined. It contains p when p is an
         element of I and is a subset of I.

      m  is a map from M onto O, m:M->O.

         Note: Some iterators extend m to m' where m'
               contains at least one of {L, U}. If m'
               is defined at L or U, the value of the
               m'(L) and m'(U) is defined by the
               iterator (and is usually a null value
               or a sentential value appropriate to
the
               iterator). The value may or may not be
               contained in O.

      A  is the set of accessible positions. It always
         contains p and is a subset of P. The set of
         accessible positions are those positions to
         which the distinguished position can be
         moved.

      X  is the set of extensible positions. It is a
         subset of P. The set of extensible positions
         are those positions at which new elements can
         be inserted into the iterator. The mapping
         from the old set of positions to the new set
         of positions is iterator defined, but is
         monotonic.

      R  is the set of replaceable positions. It is a
         subset of M. The set of replaceable positions
         are those positions where the value of the
         iterator may be changed.

      D  is the set of deletable positions. It is a
         subset of M. The set of deletable positions
         are those positions where the value of the
         iterator may be removed from the iterator.
         The mapping from the old set of positions
         to the new set of positions is iterator
         defined, but is monotonic.

   An iterator is a sequence if both I = M and A = P.
It is a temporal sequence if M = {p} and A is a subset
of {p-1, p, p+1}.

====================================================

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]