edits. What can I say?

[SVN r10992]
This commit is contained in:
Dave Abrahams
2001-09-02 04:42:43 +00:00
parent 89107738b3
commit 506334c120

View File

@@ -115,8 +115,8 @@ on other iterators (adapted iterators) and generators of new iterator
families (iterator adaptors). The Iterator Adaptor Library is an
example of policy-based design and employs template
meta-programming. We also present the Policy Adapter implementation
pattern, a strategy used by the library that can also be used to
generate new representatives of other abstract Concept families.
pattern, a strategy which can also be used to generate new
representatives of other abstract Concept families.
\end{abstract}
@@ -152,14 +152,17 @@ Concept, iterators can be both efficient and convenient to use.
The \Cpp\ Standard Library contains a wide variety of useful
iterators. Every one of the standard containers comes with constant
and mutable iterators (iterators that point to constant objects and
iterators that point to objects that can be changed or assigned to),
and also \code{reverse\_} versions of the iterators that traverse the
and mutable iterators\footnote{The term \emph{mutable iterator} refers
to iterators over objects that can be changed by assigning to the
dereferenced iterator, while \emph{constant iterator} refers to
iterators over objects that cannot be modified}, and also
\code{reverse\_} versions of those same iterators which traverse the
container in the opposite direction. The Standard also supplies
\code{istream\_\-iterator} and \code{ostream\_\-iterator} for reading
from and writing to streams, \code{insert\_iterator} and
\code{back\_insert\_iterator} for inserting elements in containers,
and \code{raw\_\-storage\_\-iterator} for initializing raw
from and writing to streams, \code{insert\_iterator},
\code{front\_insert\_iterator} and \code{back\_insert\_iterator} for
inserting elements into containers, and
\code{raw\_\-storage\_\-iterator} for initializing raw
memory~\cite{iso98:_cpp_final_draft_standard}.
Despite the many iterators supplied by the Standard Library, many
@@ -169,7 +172,7 @@ several of these, for example
\code{line\_iterator}~\cite{austern99:_gener_progr_stl}
\code{Constant\_iterator}~\cite{koenig97:_rumin_cpp}. The iterator
abstraction is so powerful, however, that we expect programmers will
always invent new iterator types.
always need to invent new iterator types.
\subsection{Adaptors}
@@ -191,8 +194,8 @@ bounds-checking to an existing iterator.
Library~\cite{TMPW00:Weiser}, which adapts containers, are themselves
adaptors over the underlying iterators.
\item smart iterators~\cite{becker98:_smart_iterators},
which adapt an iterator's dereferencing behavior by applying a
\item smart iterators~\cite{becker98:_smart_iterators}
adapt an iterator's dereferencing behavior by applying a
function object to the object being referenced and returning the
result.
@@ -235,7 +238,7 @@ have followed the lead of the standard library, which provides a
\code{base()} function to access the underlying iterator object of a
\reverseiterator\ adaptor.}
\subsection{Core Elements of the Concept}
\subsection{Core Elements of the Iterator Concept}
The first step in designing such a generalized Model is to identify
the core elements of its interface. We have identified the following
@@ -286,8 +289,9 @@ were quickly implemented using \iteratoradaptor{}:\begin{itemize}
smart pointers and applies an extra level of dereferencing.
\item Reverse Iterator Adaptor, which inverts the direction of a
\code{Base} iterator's motion.
% say something about how this one is better than the std one?
\code{Base} iterator's motion, while allowing adapted constant and
mutable iterators to interact in the expected ways. We will discuss
this further in Section \ref{sec:constant-mutable-iterations}.
\item Transform Iterator Adaptor, which applies a user-defined
function object to the underlying values when dereferenced. We will
@@ -328,7 +332,7 @@ and delegating functions and by taking care of the complex details of
iterator implementation.
The central design feature of \iteratoradaptor\ is parameterization by
an iterator policies class. The policies class is the primary
a policies class. The policies class is the primary
communication mechanism between the iterator implementer and the
\iteratoradaptor{}; it specifies how the new iterator type
behaves. Unlike the policy classes
@@ -339,12 +343,18 @@ implementation.
\subsection{Iterator Policies Class}
\label{sec:iterator-policies-class}
The following example shows how to implement the policies class for a transform
iterator adaptor: an iterator that applies some function to the value returned
by dereferencing the base iterator. The
\code{transform\_\-iterator\_\-policies} class is templated on the function
object type, and a function object is stored as a data member of the policies
class. When adapting an underlying iterator, it is easiest to store any extra state
The following example shows how to implement the policies class for a
transform iterator adaptor: an iterator that applies some function to
the value returned by dereferencing the base iterator. The
\code{transform\_\-iterator\_\-policies} class is templated on the
function object type, and a function object is stored as a data member
of the policies class.\footnote{We might instead have composed the
underlying iterator and the function object into a single \code{Base}
type, but that would have been much more work because so many useful
defaults are provided when the \code{Base} type is itself an
iterator.}
When adapting an underlying iterator, it is easiest to store any extra state
needed by the resulting adapted iterator in the policies class rather than
incorporating it into the \code{Base} type because \iteratoradaptor\
provides so many useful defaults when the \code{Base} type is an iterator.
@@ -357,11 +367,12 @@ operations to the base iterator. The main event of the
\code{transform\_\-iterator\_\-policies} class is the
\code{dereference()} member function, which simply applies the
function to the dereferenced value. The base iterator object is the
second argument to the \code{dereference()} function. The iterator
type is a template parameter to allow this policy class to be used
with any base iterator type.\footnote{The term``\code{BaseIterator}''
here is meant to denote that the \code{Base} type is expected to be an
iterator.}
second argument to the \code{dereference()} function. Because the
iterator type is a template parameter of the \code{dereference()}
function, the same concrete policies class can be used with any base
iterator type, which greatly simplifies adaptation.\footnote{The
term``\code{BaseIterator}'' here is meant to denote that the
\code{Base} type is expected to be an iterator.}
{\footnotesize
\begin{verbatim}
@@ -460,10 +471,10 @@ namespace boost {
\label{sec:iter-type-generator}
In Section~\ref{sec:iterator-policies-class} we showed how to create
the policy class for the transform iterator, so the next step is to
use the \iteratoradaptor\ template to construct the actual iterator
the policy class for the transform iterator; the next step is to use
the \iteratoradaptor\ template to construct the actual iterator
type. The best way to package the construction of the transform
iterator is to create a \emph{type generator}, which is a class
iterator is to create a \emph{type generator}: a class
template whose sole purpose is to simplify the instantiation of some
other complicated class template. It fulfills the same need as a
template typedef would if that were part of the \Cpp\ language. The
@@ -486,11 +497,11 @@ shows the type generator for the transform iterator.
\end{verbatim}
}
We use \iteratoradaptor\ to define the transform iterator type
as a nested \code{typedef} inside the
We use \iteratoradaptor\ to define the transform iterator type as a
nested \code{typedef} inside the
\code{transform\_\-iterator\_\-generator} class. The first parameter
to \iteratoradaptor\ is the base iterator type and the second
is the policies class. The remaining parameters specify the iterators
to \iteratoradaptor\ is the base iterator type and the second is the
policies class. The remaining parameters specify the iterator's
associated types and are given as \emph{named parameters}. We will
discuss this technique in \S\ref{sec:named-template-parameters}.
@@ -503,11 +514,11 @@ the \code{pointer} type defaults to \code{value\_type*} and the
\differencetype{} defaults to the \differencetype{} of
the base iterator.
It is tempting to create a \code{transform\_\-iterator} by deriving
from \iteratoradaptor\ (as an alternative to using the
generator). This approach does not work, for example, because the
It is tempting to create a \code{transform\_\-iterator} class template
which is derived from \iteratoradaptor\, instead of using the
generator. This approach does not work, for example, because the
return type of \code{operator++} of an iterator is required to be the
same iterator type, but in this case the return type would be
same iterator type, while in this case the return type would be
\iteratoradaptor\ and not \code{transform\_\-iterator}.
%It
@@ -532,14 +543,15 @@ they would have to separately construct a policies object and then the
iterator object. We therefore recommend that iterator implementers
create an \emph{object generator} function for their iterator. The
following is the generator function for the transform iterator
adaptor.\footnote{
There is precedent in the standard for calling such
an object generator, simply ``\code{transform\_iterator()}''
(e.g. \code{std::back\_inserter}), but also for the more explicit
\code{make\_} prefix (e.g. \code{std::make\_pair()}) and occasionally
for using the simple name for the adaptor type itself
(e.g. \code{std::reverse\_iterator}). In the end, the authors decided
that explicit was better than implicit. }
adaptor.\footnote{ Although there is precedent in the standard for
calling such an object generator, simply
``\code{transform\_iterator()}'' (e.g. \code{std::back\_inserter}),
the standard also uses the more explicit ``\code{make\_}'' prefix
(e.g. \code{std::make\_pair()}) and occasionally also uses the simple
name for the iterator type itself
(e.g. \code{std::reverse\_iterator}). In the end, the authors felt
that explicit was better than implicit and decided to use the
``\code{make\_}'' prefix for object generators. }
{\footnotesize
\begin{verbatim}
@@ -714,7 +726,7 @@ iterator takes its \valuetype\ from the \code{Base}
iterator's \iteratortraits{}. However, if the \code{Value} parameter \emph{is} supplied,
an adjustment is made which allows the user to more easily create a
constant iterator: if the \code{Value} parameter is \code{const T},
the \valuetype\ will just be \code{T}.Perhaps
the \valuetype\ will just be \code{T}. Perhaps
strangely, a constant iterator's \valuetype\ should never be
\code{const}, because it would prevent algorithms from declaring
modifiable temporary objects which are copied from dereferenced
@@ -812,8 +824,7 @@ associated types used to look something like this:
Unfortunately, this strategy can only take us so far. It turns out
that there are plenty of iterators which don't fit neatly into the
system for ordering defaults. For example, the specialized Transform
Iterator Adaptor described earlier
% When we reorganize the paper it may appear later. check this out.
Iterator Adaptor described in Section~\ref{sec:iterator-policies-class}
limits the category of its \code{Base} iterator to
\stlconcept{InputIterator}, so the we'd only need to supply the
\valuetype{}, \code{reference}, and \iteratorcategory\ if
@@ -840,7 +851,7 @@ an appropriately-named wrapper class for each parameter. For example:
}
Instead of passing the argument \code{Value} directly to
\iteratoradaptor\ the user passes
\iteratoradaptor\ the user can pass
\code{value\_type\_is<Value>}. The \iteratoradaptor\ has
five arguments for the associated types, each of which could be used
to specify any of the actual parameters. The
@@ -967,7 +978,9 @@ kinds of iterators should propagate the ability to interact. For
example, a reverse iterator adaptor applied to \code{C::iterator} and
\code{C::const\_iterator} should result in mutable and constant
reverse iterator types that have the same ability to interact as the
\code{Base} iterators do.
\code{Base} iterators do. The \reverseiterator{} adaptor supplied by
the Iterator Adaptor Library have this ability, although those
supplied by the \Cpp\ standard library do not.
The iterator adaptor binary operators are implemented using function
templates (as shown in the previous Subsection). This allows the same
@@ -1117,13 +1130,13 @@ dangling reference.
The \Cpp\ Standard specifies that the return type of \code{operator[]}
of a random access iterator must be ``convertible to \code{T}''. This
opens up the possibility of returning by-balue from \code{operator[]}
instead of by-reference, and thereby avoiding the above problem. This
opens up the possibility of returning by-value from \code{operator[]}
instead of by-reference, thereby avoiding the above problem. This
approach, though safer, has the disadvantage of being a less
orthogonal design since \code{operator*} is required to return the
exact type \code{T\&}, and one might think that \code{operator[]} and
\code{operator*} should be same in this respect. The \Cpp\ Standards
Committee is currently debating as to whether the random access
Committee is currently debating the question of whether the random access
iterator requirements should be changed.
Boost's \iteratoradaptor\ takes the safe route and returns the result
@@ -1143,9 +1156,11 @@ Under the current \Cpp\ Standard, you cannot assign into the result of
but instead must write \code{*(i + n) = x}.
It would be nice to return by-reference for iterators that can support
it, and by-value for the rest. However, the current
\iteratortraits\ does not provide enough information to make the
choice.
it, and by-value for the rest. However, the current \iteratortraits\
does not provide enough information to make the choice. The proposal
in~\cite{siek01:_improved_iter_cat} would solve this problem, but of
course that will take some time to gain acceptance.
% Jeremy: I didn't agree with this part, so commented it out
% temporarily. I think an iterator which can return by-reference for
@@ -1157,10 +1172,6 @@ choice.
% iterator would either return by-value for both \code{operator*} and
% \code{operator[]} or return by-reference for both.
The proposal in~\cite{siek01:_improved_iter_cat} would solve this
problem, but of course that will take some time to gain acceptance.
\section{Conclusion}
Constructing iterators and iterator adaptors is a common task for