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 .. _`Open Systems Lab`: http://www.osl.iu.edu
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de .. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
:abstract: We propose two class templates that help programmers :abstract: We propose as set of class templates that help programmers
build standard-conforming iterators and build build standard-conforming iterators and build iterators
iterators that adapt of other iterators. that adapt of other iterators.
.. contents:: Table of Contents .. contents:: Table of Contents
@@ -26,25 +26,7 @@
Iterators play an important role in modern C++ programming. The Iterators play an important role in modern C++ programming. The
iterator is the central abstraction of the algorithms of the Standard iterator is the central abstraction of the algorithms of the Standard
Library, allowing algorithms to be re-used in in a wide variety of Library, allowing algorithms to be re-used in in a wide variety of
contexts. contexts. The C++ Standard Library contains a wide variety of useful
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
iterators. Every one of the standard containers comes with constant iterators. Every one of the standard containers comes with constant
and mutable iterators[#mutable]_, and also reverse versions of those and mutable iterators[#mutable]_, and also reverse versions of those
same iterators which traverse the container in the opposite direction. 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 Despite the many iterators supplied by the Standard Library, many
obvious iterators are missing, and creating new iterator types is obvious 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] 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, however, 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.
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 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
Because iterators combine traversal, indirection, and associated type iterator to create a new one often saves work because one can reuse
exposure, it is common to want to adapt one iterator to form a new one aspect of functionality while redefining the other.
one. This strategy allows one to reuse some of original iterator's For example, the Standard provides ``reverse_iterator``, which adapts
axes of variation while redefining others. For example, the Standard any Bidirectional Iterator by inverting its direction of traversal.
provides reverse_iterator, which adapts any BidirectionalIterator by As with plain iterators, iterator adaptors defined outside the
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.
* The iterators of the View Template Library[14], which adapts * The iterators of the View Template Library[14], which adapts
containers, are themselves adaptors over the underlying iterators. 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 applying a function object to the object being referenced and
returning the result. returning the result.
* Custom iterators [4], in which a variety of adaptor types are enumerated. * 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 * Several iterator adaptors from the MTL [12]. The MTL contains a
strided iterator, where each call to ``operator++()`` moves the 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 constant iterator refers to iterators over objects that cannot be
modified. modified.
To automate the repetitive work of constructing iterators, we propose To fulfill the need for constructing adaptors, we propose the
``iterator_facade``, an iterator base class template which provides ``iterator_adaptor`` class template. The ``iterator_adaptor`` serves
the rich interface of standard iterators and delegates its as a base class for an iterator, providing the default behaviour of
implementation to member functions of the derived class. We also forwarding all operations to the adapted iterator. The user can
propose ``iterator_adaptor``, a base class generator designed selectively replace these features in a derived iterator class. The
specifically for creating iterator adaptors. Because iterators proposal also includes a number of more specialized adaptors, such as
usually have many of the features of their underlying iterator type, the ``transform_iterator`` that applies some user-specified function
the default features of ``iterator_adaptor`` are those of its base during the dereference of the iterator.
[#base]_. The user can selectively replace these features in a
derived iterator class.
.. [#base] The term "Base" is not meant to imply the use of ========================
inheritance. We have followed the lead of the standard library, Impact on the Standard
which provides a base() function to access the underlying iterator ========================
object of a reverse - iterator adaptor.
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 Design
iterators: ========
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 * dereferencing
* incrementing * incrementing
@@ -140,34 +134,51 @@ iterators:
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: value
type, reference, pointer, and iterator category. The library supports type, reference, pointer, and iterator category.
two ways of specifying these: as traditional template parameters and
also as named template parameters (described below), and uses a system The user of the ``iterator_facade`` creates a class the derives from
of smart defaults which in most cases reduces the number of these ``iterator_facade`` and defines member functions that implement the
types that must be specified. 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 The ``iterator_adaptor`` class template adapts some ``Base``{#base]_
scratch), but a generalized iterator adaptor is even more useful. An adaptor generator type to create a new iterator. ``iterator_adaptor`` derives from
allows one to build whole families of iterator instances based on existing iterators. ``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 .. [#base] The term "Base" here is not meant to imply the
implemented using iterator adaptor: 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 * Indirect Iterator Adaptor, which iterates over iterators, pointers, or smart pointers
and applies an extra level of dereferencing. and applies an extra level of dereferencing.
* Reverse Iterator Adaptor, which inverts the direction of a Base iterator's motion, * 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 while allowing adapted constant and mutable iterators to interact in the expected
ways. We will discuss this further in Section 5.2.1. 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 underlying values when dereferenced. We will show how this adaptor is implemented
in Section 3.1. in Section 3.1.
* Projection Iterator Adaptor, which is similar to Transform Iterator Adaptor except * Projection Iterator Adaptor, which is similar to Transform Iterator Adaptor except
that when dereferenced it returns by-reference instead of by-value. 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 * Filter Iterator Adaptor, which provides a view of an iterator range in which some
elements of the underlying range are skipped. elements of the underlying range are skipped.
* Counting Iterator Adaptor, which adapts any incrementable * Counting Iterator Adaptor, which adapts any incrementable
type (e.g. integers, iterators) so that incrementing/decrementing type (e.g. integers, iterators) so that incrementing/decrementing
the adapted iterator and dereferencing it produces successive values the adapted iterator and dereferencing it produces successive values
of the Base type. of the Base type.
* Function Output Iterator Adaptor, which makes it easier to create custom output * Function Output Iterator Adaptor, which makes it easier to create custom output
iterators. iterators.
@@ -203,31 +210,11 @@ LEDA [10] and Stanford GraphBase [8], to the BGL interface (which
requires C++ Standard compliant iterators). 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 Proposed Text
@@ -374,3 +361,8 @@ xxx
explicit iterator_adaptor(Base iter); explicit iterator_adaptor(Base iter);
Base base() const; Base base() const;
}; };