diff --git a/tmpw2001-paper/iter-adaptor.tex b/tmpw2001-paper/iter-adaptor.tex index 7843182..229b2aa 100644 --- a/tmpw2001-paper/iter-adaptor.tex +++ b/tmpw2001-paper/iter-adaptor.tex @@ -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}. 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