made a little progress, rewrote a bunch

[SVN r1164]
This commit is contained in:
Jeremy Siek
2003-04-19 23:47:51 +00:00
parent c3d067d4c1
commit 725bef482b

View File

@@ -13,9 +13,9 @@
.. _`Open Systems Lab`: http://www.osl.iu.edu
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
:abstract: We propose two class templates that help programmers
build standard-conforming iterators and build
iterators that adapt of other iterators.
:abstract: We propose as set of class templates that help programmers
build standard-conforming iterators and build iterators
that adapt of other iterators.
.. contents:: Table of Contents
@@ -26,25 +26,7 @@
Iterators play an important role in modern C++ programming. The
iterator is the central abstraction of the algorithms of the Standard
Library, allowing algorithms to be re-used in in a wide variety of
contexts.
Iterators
=========
The power of iterators derives from several key features:
- Iterators form a rich family of concepts [#concept]_ whose
functionality varies along several axes: movement, dereferencing,
and associated type exposure.
- The existing iterator concepts of the C++ standard form a refinement
hierarchy which allows the same basic interface elements to
implement diverse functionality.
- Because built-in pointer types model the RandomAccessIterator
concept, iterators can be both efficient and convenient to use.
The C++ Standard Library contains a wide variety of useful
contexts. The C++ Standard Library contains a wide variety of useful
iterators. Every one of the standard containers comes with constant
and mutable iterators[#mutable]_, and also reverse versions of those
same iterators which traverse the container in the opposite direction.
@@ -57,40 +39,48 @@ The Standard also supplies ``istream_iterator`` and
Despite the many iterators supplied by the Standard Library, many
obvious iterators are missing, and creating new iterator types is
still a common task for C++ programmers. The literature documents
several of these, for example line_iterator [3] Constant_iterator
several of these, for example line_iterator [3] and Constant_iterator
[9]. The iterator abstraction is so powerful, however, that we expect
programmers will always need to invent new iterator types.
Creating a standards conforming iterator is a non-trivial task.
Despite the fact that it is easy to create iterators that almost
conform to the standard, there are several subtle points that make
creating a conforming iterator difficult. Further, the iterator
interface is rich, containing many operators that are technically
redundant. As a result, much of the work of creating an iterator is
tedious. To automate the repetitive work of constructing iterators, we
propose ``iterator_facade``, an iterator base class template which
provides the rich interface of standard iterators and delegates its
implementation to member functions of the derived class. In addition
to shortening the amount of code necessary to create an iterator, the
``iterator_facade`` also provides compile-time error detection. Many
iterator implementation mistakes that often go unnoticed are turned
into compile-time errors because the derived class implementation must
match the expectations of the ``iterator_facade``.
Adaptors
========
Because iterators combine traversal, indirection, and associated type
exposure, it is common to want to adapt one iterator to form a new
one. This strategy allows one to reuse some of original iterator's
axes of variation while redefining others. For example, the Standard
provides reverse_iterator, which adapts any BidirectionalIterator by
inverting its direction of traversal. As with plain iterators,
iterator adaptors defined outside the Standard have become commonplace
in the literature:
A common pattern of iterator construction is adapting one iterator to
form a new one. The functionality of an iterator is composed of two
orthogonal aspects: traversal and indirection. Adapting an old
iterator to create a new one often saves work because one can reuse
one aspect of functionality while redefining the other.
For example, the Standard provides ``reverse_iterator``, which adapts
any Bidirectional Iterator by inverting its direction of traversal.
As with plain iterators, iterator adaptors defined outside the
Standard have become commonplace in the literature:
* Checked iter[13] adds bounds-checking to an existing iterator.
* The iterators of the View Template Library[14], which adapts
containers, are themselves adaptors over the underlying iterators.
* smart iterators [5] adapt an iterator's dereferencing behavior by
* Smart iterators [5] adapt an iterator's dereferencing behavior by
applying a function object to the object being referenced and
returning the result.
* Custom iterators [4], in which a variety of adaptor types are enumerated.
* compound iterators [1], which access a slice out of a container of containers.
* Compound iterators [1], which access a slice out of a container of containers.
* Several iterator adaptors from the MTL [12]. The MTL contains a
strided iterator, where each call to ``operator++()`` moves the
@@ -107,29 +97,33 @@ in the literature:
constant iterator refers to iterators over objects that cannot be
modified.
To automate the repetitive work of constructing iterators, we propose
``iterator_facade``, an iterator base class template which provides
the rich interface of standard iterators and delegates its
implementation to member functions of the derived class. We also
propose ``iterator_adaptor``, a base class generator designed
specifically for creating iterator adaptors. Because iterators
usually have many of the features of their underlying iterator type,
the default features of ``iterator_adaptor`` are those of its base
[#base]_. The user can selectively replace these features in a
derived iterator class.
To fulfill the need for constructing adaptors, we propose the
``iterator_adaptor`` class template. The ``iterator_adaptor`` serves
as a base class for an iterator, providing the default behaviour of
forwarding all operations to the adapted iterator. The user can
selectively replace these features in a derived iterator class. The
proposal also includes a number of more specialized adaptors, such as
the ``transform_iterator`` that applies some user-specified function
during the dereference of the iterator.
.. [#base] The term "Base" is not meant to imply the use of
inheritance. We have followed the lead of the standard library,
which provides a base() function to access the underlying iterator
object of a reverse - iterator adaptor.
========================
Impact on the Standard
========================
Core Elements of the Iterator Concept
=====================================
This proposal is purely an addition to the C++ standard library.
However, note that this proposal relies on the proposal for New
Iterator Concepts.
The first step in designing such a generalized model of the iterator concept is to identify
the core elements of its interface. We have identified the following core behaviors for
iterators:
========
Design
========
Iterator Facade
===============
While the iterator interface is rich, there is a core subset of the
interface that is necessary for all the functionality. We have
identified the following core behaviors for iterators:
* dereferencing
* incrementing
@@ -140,34 +134,51 @@ iterators:
In addition to the behaviors listed above, the core interface elements
include the associated types exposed through iterator traits: value
type, reference, pointer, and iterator category. The library supports
two ways of specifying these: as traditional template parameters and
also as named template parameters (described below), and uses a system
of smart defaults which in most cases reduces the number of these
types that must be specified.
type, reference, pointer, and iterator category.
The user of the ``iterator_facade`` creates a class the derives from
``iterator_facade`` and defines member functions that implement the
core behaviours. The member functions are required to have the
following interface. In the following, ``self`` is the type of the
derived iterator.
::
reference dereference() const;
bool equal(self const& x) const;
void advance(difference_type n);
void increment();
void decrement();
difference_type distance_to(self const& y) const;
From Building Models to Building Adaptors
=========================================
Iterator Adaptor
================
A generalized iterator generator is useful (helping to create new iterator types from
scratch), but a generalized iterator adaptor is even more useful. An adaptor generator
allows one to build whole families of iterator instances based on existing iterators.
The ``iterator_adaptor`` class template adapts some ``Base``{#base]_
type to create a new iterator. ``iterator_adaptor`` derives from
``iterator_facade`` and implements the core interface in terms of the
``Base`` type. In essense, the ``iterator_adaptor`` merely forwards
all operations to the ``Base`` type. An object of the ``Base`` type is
a data member of ``iterator_adaptor``.
In the Boost Iterator Adaptor Library, the iterator adaptor class template plays
the roles of both iterator generator and iterator adaptor generator. The behaviors of
iterator adaptor instances are supplied through a policies class [2] which allows
users to specialize adaptation. Users go beyond generating new iterator types to easily
generating new iterator adaptor families.
The library contains several examples of specialized adaptors which were quickly
implemented using iterator adaptor:
.. [#base] The term "Base" here is not meant to imply the
class being inherited from. We have followed the lead of the
standard library, which provides a base() function to access the
underlying iterator object of a ``reverse_iterator`` adaptor.
The user of ``iterator_adaptor`` constructs a class that derives from
``iterator_adaptor`` and then selectively overrides some of the core
operations. In addition, the derived class will typically need to
define some constructors.
The library also contains several examples of specialized adaptors
which were easily implemented using ``iterator_adaptor``:
* Indirect Iterator Adaptor, which iterates over iterators, pointers, 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.
@@ -176,21 +187,17 @@ implemented using iterator adaptor:
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.
@@ -203,31 +210,11 @@ LEDA [10] and Stanford GraphBase [8], to the BGL interface (which
requires C++ Standard compliant iterators).
The Boost iterator adaptor Class Template
=========================================
The iterator adaptor class template simplifies the creation of iterators by automating
the implementation of redundant operators and delegating functions and by taking
care of the complex details of iterator implementation.
The central design feature of iterator adaptor is parameterization by
a policies class. The policies class is the primary communication
mechanism between the iterator implementer and the iterator adaptor;
it specifies how the new iterator type behaves. Unlike the policy
classes in [2], we group several policies into a single class as this
proved more convenient for iterator implementation.
========================
Impact on the Standard
========================
xxxx
========
Design
========
xxx
===============
Proposed Text
@@ -374,3 +361,8 @@ xxx
explicit iterator_adaptor(Base iter);
Base base() const;
};