forked from boostorg/iterator
made a little progress, rewrote a bunch
[SVN r1164]
This commit is contained in:
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user