From cc8157a4e635b43fd08b6606da29a503ff021316 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 20 Apr 2003 10:26:35 +0000 Subject: [PATCH] Some Updates [SVN r1167] --- doc/facade-and-adaptor.rst | 161 +++++++++++++++++++------------------ 1 file changed, 81 insertions(+), 80 deletions(-) diff --git a/doc/facade-and-adaptor.rst b/doc/facade-and-adaptor.rst index f824d34..188baad 100755 --- a/doc/facade-and-adaptor.rst +++ b/doc/facade-and-adaptor.rst @@ -28,7 +28,7 @@ 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. 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 +and mutable iterators [#mutable]_, and also reverse versions of those same iterators which traverse the container in the opposite direction. The Standard also supplies ``istream_iterator`` and ``ostream_iterator`` for reading from and writing to streams, @@ -36,38 +36,38 @@ The Standard also supplies ``istream_iterator`` and ``back_insert_iterator`` for inserting elements into containers, and ``raw_storage_iterator`` for initializing raw memory [7]. -Despite the many iterators supplied by the Standard Library, many -obvious iterators are missing, and creating new iterator types is +Despite the many iterators supplied by the Standard Library, obvious +and useful 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] and Constant_iterator -[9]. The iterator abstraction is so powerful, however, that we expect +[9]. The iterator abstraction is so powerful 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 +Although it is easy to create iterators that *almost* conform to the +standard, the iterator requirements contain subtleties which can make +creating an iterator which *actually* conforms quite difficult. +Further, the iterator interface is rich, containing many operators +that are technically redundant and tedious to implement. 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 reducing the amount of code necessary to create an iterator, the +``iterator_facade`` also provides compile-time error detection. +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``. -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: +A common pattern of iterator construction is the adaptation of one +iterator to form a new one. The functionality of an iterator is +composed of four orthogonal aspects: traversal, indirection, equality +comparison and distance measurement. 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. @@ -82,12 +82,11 @@ Standard have become commonplace in the literature: * 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 iterator ahead by some constant factor, and a scaled iterator, which multiplies the dereferenced value by some constant. - .. [#concept] We use the term concept to mean a set of requirements that a type must satisfy to be used with a particular template parameter. @@ -98,13 +97,14 @@ Standard have become commonplace in the literature: modified. 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. +``iterator_adaptor`` class template. Instantiations of +``iterator_adaptor`` serve as a base classes for new iterators, +providing the default behaviour of forwarding all operations to the +underlying iterator. The user can selectively replace these features +in the derived iterator class. This 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. ======================== Impact on the Standard @@ -122,7 +122,7 @@ 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 +interface that is necessary for all the functionality. We have identified the following core behaviors for iterators: * dereferencing @@ -133,11 +133,11 @@ identified the following core behaviors for iterators: * distance measurement 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. +include the associated types exposed through iterator traits: +``value_type``, ``reference``, ``pointer``, and ``iterator_category``. -The user of the ``iterator_facade`` creates a class derived from an -instantiation of ``iterator_facade`` which defines member functions +The user of ``iterator_facade`` derives his iterator class from an +instantiation of ``iterator_facade`` and defines member functions implementing the core behaviors. The following table describes expressions which are required to be valid depending on the category of the derived iterator type. @@ -176,13 +176,11 @@ Iterator Adaptor ================ The ``iterator_adaptor`` class template adapts some ``Base`` [#base]_ -type to create a new iterator. Instantiations of ``iterator_adaptor`` +type to create a new iterator. Instantiations of ``iterator_adaptor`` are derived from a corresponding instantiation of ``iterator_facade`` and implement the core behaviors in terms of the ``Base`` type. In -essence, the ``iterator_adaptor`` merely forwards all operations to -the ``Base`` type. An object of the ``Base`` type is a data member of -``iterator_adaptor``. - +essence, ``iterator_adaptor`` merely forwards all operations to an +instance of the ``Base`` type, which it stores as a member. .. [#base] The term "Base" here does not refer to a base class and is not meant to imply the use of derivation. We have followed the lead @@ -192,51 +190,54 @@ the ``Base`` type. An object of the ``Base`` type is a data member of The user of ``iterator_adaptor`` creates a class derived from an instantiation of ``iterator_adaptor`` and then selectively overrides some of the core operations by implementing the (non-virtual) member -functions described in the table above. In addition, the derived -class will typically need to define some constructors. +functions described in the table above. -The library also contains several examples of specialized adaptors +.. In addition, the derived + class will typically need to define some constructors. + +.. Jeremy, that last sentence is also true of iterator_facade. + Perhaps we ought to cover the issue of constructors separately. + +Specialized Adaptors +==================== + +This proposal 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. - -* Transform Iterator Adaptor, which applies a user-defined function object to the - 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. - -Based on the examples in the library, users have generated many new adaptors, -among them a permutation adaptor which applies some permutation to a RandomAccessIterator, -and a strided adaptor, which adapts a RandomAccessIterator by multiplying -its unit of motion by a constant factor. In addition, the Boost Graph Library -(BGL) uses iterator adaptors to adapt other graph libraries, such as -LEDA [10] and Stanford GraphBase [8], to the BGL interface (which -requires C++ Standard compliant iterators). +* ``indirect_iterator``, which iterates over iterators, pointers, + or smart pointers and applies an extra level of dereferencing. +* A new ``reverse_iterator``, which inverts the direction of a Base + iterator's motion, while allowing adapted constant and mutable + iterators to interact in the expected ways (unlike those in most + implementations of C++98). +* ``transform_iterator``, which applies a user-defined function object + to the underlying values when dereferenced. +* ``projection_iterator``, which is similar to ``transform_iterator`` + except that when dereferenced it returns a reference instead of + a value. +* ``filter_iterator``, which provides a view of an iterator range in + which some elements of the underlying range are skipped. +* ``counting_iterator``, 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``, which makes it easier to create custom + output iterators. +Based on examples in the Boost library, users have generated many new +adaptors, among them a permutation adaptor which applies some +permutation to a RandomAccessIterator, and a strided adaptor, which +adapts a RandomAccessIterator by multiplying its unit of motion by a +constant factor. In addition, the Boost Graph Library (BGL) uses +iterator adaptors to adapt other graph libraries, such as LEDA [10] +and Stanford GraphBase [8], to the BGL interface (which requires C++ +Standard compliant iterators). =============== Proposed Text