forked from boostorg/iterator
Some Updates
[SVN r1167]
This commit is contained in:
@@ -36,38 +36,38 @@ The Standard also supplies ``istream_iterator`` and
|
|||||||
``back_insert_iterator`` for inserting elements into containers, and
|
``back_insert_iterator`` for inserting elements into containers, and
|
||||||
``raw_storage_iterator`` for initializing raw memory [7].
|
``raw_storage_iterator`` for initializing raw memory [7].
|
||||||
|
|
||||||
Despite the many iterators supplied by the Standard Library, many
|
Despite the many iterators supplied by the Standard Library, obvious
|
||||||
obvious iterators are missing, and creating new iterator types is
|
and useful iterators are missing, and creating new iterator types is
|
||||||
still a common task for C++ programmers. The literature documents
|
still a common task for C++ programmers. The literature documents
|
||||||
several of these, for example line_iterator [3] and Constant_iterator
|
several of these, for example line_iterator [3] and Constant_iterator
|
||||||
[9]. The iterator abstraction is so powerful, however, that we expect
|
[9]. The iterator abstraction is so powerful that we expect
|
||||||
programmers will always need to invent new iterator types.
|
programmers will always need to invent new iterator types.
|
||||||
|
|
||||||
Creating a standards conforming iterator is a non-trivial task.
|
Although it is easy to create iterators that *almost* conform to the
|
||||||
Despite the fact that it is easy to create iterators that almost
|
standard, the iterator requirements contain subtleties which can make
|
||||||
conform to the standard, there are several subtle points that make
|
creating an iterator which *actually* conforms quite difficult.
|
||||||
creating a conforming iterator difficult. Further, the iterator
|
Further, the iterator interface is rich, containing many operators
|
||||||
interface is rich, containing many operators that are technically
|
that are technically redundant and tedious to implement. To automate
|
||||||
redundant. As a result, much of the work of creating an iterator is
|
the repetitive work of constructing iterators, we propose
|
||||||
tedious. To automate the repetitive work of constructing iterators, we
|
``iterator_facade``, an iterator base class template which provides
|
||||||
propose ``iterator_facade``, an iterator base class template which
|
the rich interface of standard iterators and delegates its
|
||||||
provides the rich interface of standard iterators and delegates its
|
|
||||||
implementation to member functions of the derived class. In addition
|
implementation to member functions of the derived class. In addition
|
||||||
to shortening the amount of code necessary to create an iterator, the
|
to reducing the amount of code necessary to create an iterator, the
|
||||||
``iterator_facade`` also provides compile-time error detection. Many
|
``iterator_facade`` also provides compile-time error detection.
|
||||||
iterator implementation mistakes that often go unnoticed are turned
|
Iterator implementation mistakes that often go unnoticed are turned
|
||||||
into compile-time errors because the derived class implementation must
|
into compile-time errors because the derived class implementation must
|
||||||
match the expectations of the ``iterator_facade``.
|
match the expectations of the ``iterator_facade``.
|
||||||
|
|
||||||
A common pattern of iterator construction is adapting one iterator to
|
A common pattern of iterator construction is the adaptation of one
|
||||||
form a new one. The functionality of an iterator is composed of two
|
iterator to form a new one. The functionality of an iterator is
|
||||||
orthogonal aspects: traversal and indirection. Adapting an old
|
composed of four orthogonal aspects: traversal, indirection, equality
|
||||||
iterator to create a new one often saves work because one can reuse
|
comparison and distance measurement. Adapting an old iterator to
|
||||||
one aspect of functionality while redefining the other.
|
create a new one often saves work because one can reuse one aspect of
|
||||||
For example, the Standard provides ``reverse_iterator``, which adapts
|
functionality while redefining the other. For example, the Standard
|
||||||
any Bidirectional Iterator by inverting its direction of traversal.
|
provides ``reverse_iterator``, which adapts any Bidirectional Iterator
|
||||||
As with plain iterators, iterator adaptors defined outside the
|
by inverting its direction of traversal. As with plain iterators,
|
||||||
Standard have become commonplace in the literature:
|
iterator adaptors defined outside the Standard have become commonplace
|
||||||
|
in the literature:
|
||||||
|
|
||||||
* Checked iter[13] adds bounds-checking to an existing iterator.
|
* Checked iter[13] adds bounds-checking to an existing iterator.
|
||||||
|
|
||||||
@@ -87,7 +87,6 @@ Standard have become commonplace in the literature:
|
|||||||
iterator ahead by some constant factor, and a scaled iterator, which
|
iterator ahead by some constant factor, and a scaled iterator, which
|
||||||
multiplies the dereferenced value by some constant.
|
multiplies the dereferenced value by some constant.
|
||||||
|
|
||||||
|
|
||||||
.. [#concept] We use the term concept to mean a set of requirements
|
.. [#concept] We use the term concept to mean a set of requirements
|
||||||
that a type must satisfy to be used with a particular template
|
that a type must satisfy to be used with a particular template
|
||||||
parameter.
|
parameter.
|
||||||
@@ -98,13 +97,14 @@ Standard have become commonplace in the literature:
|
|||||||
modified.
|
modified.
|
||||||
|
|
||||||
To fulfill the need for constructing adaptors, we propose the
|
To fulfill the need for constructing adaptors, we propose the
|
||||||
``iterator_adaptor`` class template. The ``iterator_adaptor`` serves
|
``iterator_adaptor`` class template. Instantiations of
|
||||||
as a base class for an iterator, providing the default behaviour of
|
``iterator_adaptor`` serve as a base classes for new iterators,
|
||||||
forwarding all operations to the adapted iterator. The user can
|
providing the default behaviour of forwarding all operations to the
|
||||||
selectively replace these features in a derived iterator class. The
|
underlying iterator. The user can selectively replace these features
|
||||||
proposal also includes a number of more specialized adaptors, such as
|
in the derived iterator class. This proposal also includes a number
|
||||||
the ``transform_iterator`` that applies some user-specified function
|
of more specialized adaptors, such as the ``transform_iterator`` that
|
||||||
during the dereference of the iterator.
|
applies some user-specified function during the dereference of the
|
||||||
|
iterator.
|
||||||
|
|
||||||
========================
|
========================
|
||||||
Impact on the Standard
|
Impact on the Standard
|
||||||
@@ -133,11 +133,11 @@ identified the following core behaviors for iterators:
|
|||||||
* distance measurement
|
* distance measurement
|
||||||
|
|
||||||
In addition to the behaviors listed above, the core interface elements
|
In addition to the behaviors listed above, the core interface elements
|
||||||
include the associated types exposed through iterator traits: value
|
include the associated types exposed through iterator traits:
|
||||||
type, reference, pointer, and iterator category.
|
``value_type``, ``reference``, ``pointer``, and ``iterator_category``.
|
||||||
|
|
||||||
The user of the ``iterator_facade`` creates a class derived from an
|
The user of ``iterator_facade`` derives his iterator class from an
|
||||||
instantiation of ``iterator_facade`` which defines member functions
|
instantiation of ``iterator_facade`` and defines member functions
|
||||||
implementing the core behaviors. The following table describes
|
implementing the core behaviors. The following table describes
|
||||||
expressions which are required to be valid depending on the category
|
expressions which are required to be valid depending on the category
|
||||||
of the derived iterator type.
|
of the derived iterator type.
|
||||||
@@ -179,10 +179,8 @@ The ``iterator_adaptor`` class template adapts some ``Base`` [#base]_
|
|||||||
type to create a new iterator. Instantiations of ``iterator_adaptor``
|
type to create a new iterator. Instantiations of ``iterator_adaptor``
|
||||||
are derived from a corresponding instantiation of ``iterator_facade``
|
are derived from a corresponding instantiation of ``iterator_facade``
|
||||||
and implement the core behaviors in terms of the ``Base`` type. In
|
and implement the core behaviors in terms of the ``Base`` type. In
|
||||||
essence, the ``iterator_adaptor`` merely forwards all operations to
|
essence, ``iterator_adaptor`` merely forwards all operations to an
|
||||||
the ``Base`` type. An object of the ``Base`` type is a data member of
|
instance of the ``Base`` type, which it stores as a member.
|
||||||
``iterator_adaptor``.
|
|
||||||
|
|
||||||
|
|
||||||
.. [#base] The term "Base" here does not refer to a base class and is
|
.. [#base] The term "Base" here does not refer to a base class and is
|
||||||
not meant to imply the use of derivation. We have followed the lead
|
not meant to imply the use of derivation. We have followed the lead
|
||||||
@@ -192,51 +190,54 @@ the ``Base`` type. An object of the ``Base`` type is a data member of
|
|||||||
The user of ``iterator_adaptor`` creates a class derived from an
|
The user of ``iterator_adaptor`` creates a class derived from an
|
||||||
instantiation of ``iterator_adaptor`` and then selectively overrides
|
instantiation of ``iterator_adaptor`` and then selectively overrides
|
||||||
some of the core operations by implementing the (non-virtual) member
|
some of the core operations by implementing the (non-virtual) member
|
||||||
functions described in the table above. In addition, the derived
|
functions described in the table above.
|
||||||
|
|
||||||
|
.. In addition, the derived
|
||||||
class will typically need to define some constructors.
|
class will typically need to define some constructors.
|
||||||
|
|
||||||
The library also contains several examples of specialized adaptors
|
.. Jeremy, that last sentence is also true of iterator_facade.
|
||||||
|
Perhaps we ought to cover the issue of constructors separately.
|
||||||
|
|
||||||
|
Specialized Adaptors
|
||||||
|
====================
|
||||||
|
|
||||||
|
This proposal also contains several examples of specialized adaptors
|
||||||
which were easily implemented using ``iterator_adaptor``:
|
which were easily implemented using ``iterator_adaptor``:
|
||||||
|
|
||||||
* Indirect Iterator Adaptor, which iterates over iterators, pointers, or smart pointers
|
* ``indirect_iterator``, which iterates over iterators, pointers,
|
||||||
and applies an extra level of dereferencing.
|
or smart pointers and applies an extra level of dereferencing.
|
||||||
|
|
||||||
* Reverse Iterator Adaptor, which inverts the direction of a Base iterator's motion,
|
|
||||||
while allowing adapted constant and mutable iterators to interact in the expected
|
|
||||||
ways. We will discuss this further in Section 5.2.1.
|
|
||||||
|
|
||||||
* Transform Iterator Adaptor, which applies a user-defined function object to the
|
|
||||||
underlying values when dereferenced. We will show how this adaptor is implemented
|
|
||||||
in Section 3.1.
|
|
||||||
|
|
||||||
* Projection Iterator Adaptor, which is similar to Transform Iterator Adaptor except
|
|
||||||
that when dereferenced it returns by-reference instead of by-value.
|
|
||||||
|
|
||||||
* Filter Iterator Adaptor, which provides a view of an iterator range in which some
|
|
||||||
elements of the underlying range are skipped.
|
|
||||||
|
|
||||||
* Counting Iterator Adaptor, which adapts any incrementable
|
|
||||||
type (e.g. integers, iterators) so that incrementing/decrementing
|
|
||||||
the adapted iterator and dereferencing it produces successive values
|
|
||||||
of the Base type.
|
|
||||||
|
|
||||||
* Function Output Iterator Adaptor, which makes it easier to create custom output
|
|
||||||
iterators.
|
|
||||||
|
|
||||||
Based on the examples in the library, users have generated many new adaptors,
|
|
||||||
among them a permutation adaptor which applies some permutation to a RandomAccessIterator,
|
|
||||||
and a strided adaptor, which adapts a RandomAccessIterator by multiplying
|
|
||||||
its unit of motion by a constant factor. In addition, the Boost Graph Library
|
|
||||||
(BGL) uses iterator adaptors to adapt other graph libraries, such as
|
|
||||||
LEDA [10] and Stanford GraphBase [8], to the BGL interface (which
|
|
||||||
requires C++ Standard compliant iterators).
|
|
||||||
|
|
||||||
|
* A new ``reverse_iterator``, which inverts the direction of a Base
|
||||||
|
iterator's motion, while allowing adapted constant and mutable
|
||||||
|
iterators to interact in the expected ways (unlike those in most
|
||||||
|
implementations of C++98).
|
||||||
|
|
||||||
|
* ``transform_iterator``, which applies a user-defined function object
|
||||||
|
to the underlying values when dereferenced.
|
||||||
|
|
||||||
|
* ``projection_iterator``, which is similar to ``transform_iterator``
|
||||||
|
except that when dereferenced it returns a reference instead of
|
||||||
|
a value.
|
||||||
|
|
||||||
|
* ``filter_iterator``, which provides a view of an iterator range in
|
||||||
|
which some elements of the underlying range are skipped.
|
||||||
|
|
||||||
|
* ``counting_iterator``, which adapts any incrementable type
|
||||||
|
(e.g. integers, iterators) so that incrementing/decrementing the
|
||||||
|
adapted iterator and dereferencing it produces successive values of
|
||||||
|
the Base type.
|
||||||
|
|
||||||
|
* ``function_output_iterator``, which makes it easier to create custom
|
||||||
|
output iterators.
|
||||||
|
|
||||||
|
Based on examples in the Boost library, users have generated many new
|
||||||
|
adaptors, among them a permutation adaptor which applies some
|
||||||
|
permutation to a RandomAccessIterator, and a strided adaptor, which
|
||||||
|
adapts a RandomAccessIterator by multiplying its unit of motion by a
|
||||||
|
constant factor. In addition, the Boost Graph Library (BGL) uses
|
||||||
|
iterator adaptors to adapt other graph libraries, such as LEDA [10]
|
||||||
|
and Stanford GraphBase [8], to the BGL interface (which requires C++
|
||||||
|
Standard compliant iterators).
|
||||||
|
|
||||||
===============
|
===============
|
||||||
Proposed Text
|
Proposed Text
|
||||||
|
Reference in New Issue
Block a user