mirror of
https://github.com/boostorg/iterator.git
synced 2025-07-21 16:42:09 +02:00
factored iterator facade stuff into several files
[SVN r19464]
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@ -164,213 +164,12 @@ interoperability without introducing unwanted overloads.
|
|||||||
Iterator Facade
|
Iterator Facade
|
||||||
===============
|
===============
|
||||||
|
|
||||||
While the iterator interface is rich, there is a core subset of the
|
.. include:: iterator_facade_body.rst
|
||||||
interface that is necessary for all the functionality. We have
|
|
||||||
identified the following core behaviors for iterators:
|
|
||||||
|
|
||||||
* dereferencing
|
|
||||||
* incrementing
|
|
||||||
* decrementing
|
|
||||||
* equality comparison
|
|
||||||
* random-access motion
|
|
||||||
* distance measurement
|
|
||||||
|
|
||||||
In addition to the behaviors listed above, the core interface elements
|
|
||||||
include the associated types exposed through iterator traits:
|
|
||||||
``value_type``, ``reference``, ``difference_type``, and
|
|
||||||
``iterator_category``.
|
|
||||||
|
|
||||||
Iterator facade uses the Curiously Recurring Template Pattern (CRTP)
|
|
||||||
[Cop95]_ so that the user can specify the behavior of
|
|
||||||
``iterator_facade`` in a derived class. Former designs used policy
|
|
||||||
objects to specify the behavior. The proposal does not use policy
|
|
||||||
objects for several reasons:
|
|
||||||
|
|
||||||
1. the creation and eventual copying of the policy object may create
|
|
||||||
overhead that can be avoided with the current approach.
|
|
||||||
|
|
||||||
2. The policy object approach does not allow for custom constructors
|
|
||||||
on the created iterator types, an essential feature if
|
|
||||||
``iterator_facade`` should be used in other library
|
|
||||||
implementations.
|
|
||||||
|
|
||||||
3. Without the use of CRTP, the standard requirement that an
|
|
||||||
iterator's ``operator++`` returns the iterator type itself means
|
|
||||||
that all iterators generated by ``iterator_facade`` would be
|
|
||||||
instantiations of ``iterator_facade``. Cumbersome type generator
|
|
||||||
metafunctions would be needed to build new parameterized
|
|
||||||
iterators, and a separate ``iterator_adaptor`` layer would be
|
|
||||||
impossible.
|
|
||||||
|
|
||||||
Usage
|
|
||||||
-----
|
|
||||||
|
|
||||||
The user of ``iterator_facade`` derives his iterator class from an
|
|
||||||
instantiation of ``iterator_facade`` which takes the derived iterator
|
|
||||||
class as the first template parameter. The order of the other
|
|
||||||
template parameters to ``iterator_facade`` have been carefully chosen
|
|
||||||
to take advantage of useful defaults. For example, when defining a
|
|
||||||
constant lvalue iterator, the user can pass a const-qualified version
|
|
||||||
of the iterator's ``value_type`` as ``iterator_facade``\ 's ``Value``
|
|
||||||
parameter and omit the ``Reference`` parameter which follows.
|
|
||||||
|
|
||||||
The derived iterator class must define member functions implementing
|
|
||||||
the iterator's core behaviors. The following table describes
|
|
||||||
expressions which are required to be valid depending on the category
|
|
||||||
of the derived iterator type. These member functions are described
|
|
||||||
briefly below and in more detail in the `iterator facade
|
|
||||||
requirements`_.
|
|
||||||
|
|
||||||
+------------------------+-------------------------------+
|
|
||||||
|Expression |Effects |
|
|
||||||
+========================+===============================+
|
|
||||||
|``i.dereference()`` |Access the value referred to |
|
|
||||||
+------------------------+-------------------------------+
|
|
||||||
|``i.equal(j)`` |Compare for equality with ``j``|
|
|
||||||
+------------------------+-------------------------------+
|
|
||||||
|``i.increment()`` |Advance by one position |
|
|
||||||
+------------------------+-------------------------------+
|
|
||||||
|``i.decrement()`` |Retreat by one position |
|
|
||||||
+------------------------+-------------------------------+
|
|
||||||
|``i.advance(n)`` |Advance by ``n`` positions |
|
|
||||||
+------------------------+-------------------------------+
|
|
||||||
|``i.distance_to(j)`` |Measure the distance to ``j`` |
|
|
||||||
+------------------------+-------------------------------+
|
|
||||||
|
|
||||||
.. Should we add a comment that a zero overhead implementation of iterator_facade
|
|
||||||
is possible with proper inlining?
|
|
||||||
|
|
||||||
In addition to implementing the core interface functions, an iterator
|
|
||||||
derived from ``iterator_facade`` typically defines several
|
|
||||||
constructors. To model any of the standard iterator concepts, the
|
|
||||||
iterator must at least have a copy constructor. Also, if the iterator
|
|
||||||
type ``X`` is meant to be automatically interoperate with another
|
|
||||||
iterator type ``Y`` (as with constant and mutable iterators) then
|
|
||||||
there must be an implicit conversion from ``X`` to ``Y`` or from ``Y``
|
|
||||||
to ``X`` (but not both), typically implemented as a conversion
|
|
||||||
constructor. Finally, if the iterator is to model Forward Traversal
|
|
||||||
Iterator or a more-refined iterator concept, a default constructor is
|
|
||||||
required.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Iterator Core Access
|
|
||||||
====================
|
|
||||||
|
|
||||||
``iterator_facade`` and the operator implementations need to be able
|
|
||||||
to access the core member functions in the derived class. Making the
|
|
||||||
core member functions public would expose an implementation detail to
|
|
||||||
the user. This proposal frees the public interface of the derived
|
|
||||||
iterator type from any implementation detail.
|
|
||||||
|
|
||||||
Preventing direct access to the core member functions has two
|
|
||||||
advantages. First, there is no possibility for the user to accidently
|
|
||||||
use a member function of the iterator when a member of the value_type
|
|
||||||
was intended. This has been an issue with smart pointer
|
|
||||||
implementations in the past. The second and main advantage is that
|
|
||||||
library implementers can freely exchange a hand-rolled iterator
|
|
||||||
implementation for one based on ``iterator_facade`` without fear of
|
|
||||||
breaking code that was accessing the public core member functions
|
|
||||||
directly.
|
|
||||||
|
|
||||||
In a naive implementation, keeping the derived class' core member
|
|
||||||
functions private would require it to grant friendship to
|
|
||||||
``iterator_facade`` and each of the seven operators. In order to
|
|
||||||
reduce the burden of limiting access, this proposal provides
|
|
||||||
``iterator_core_access``, a class that acts as a gateway to the core
|
|
||||||
member functions in the derived iterator class. The author of the
|
|
||||||
derived class only needs to grant friendship to
|
|
||||||
``iterator_core_access`` to make his core member functions available
|
|
||||||
to the library.
|
|
||||||
|
|
||||||
.. This is no long uptodate -thw
|
|
||||||
.. Yes it is; I made sure of it! -DWA
|
|
||||||
|
|
||||||
``iterator_core_access`` will be typically implemented as an empty
|
|
||||||
class containing only private static member functions which invoke the
|
|
||||||
iterator core member functions. There is, however, no need to
|
|
||||||
standardize the gateway protocol. Note that even if
|
|
||||||
``iterator_core_access`` used public member functions it would not
|
|
||||||
open a safety loophole, as every core member function preserves the
|
|
||||||
invariants of the iterator.
|
|
||||||
|
|
||||||
``operator[]``
|
|
||||||
================
|
|
||||||
|
|
||||||
The indexing operator for a generalized iterator presents special
|
|
||||||
challenges. A random access iterator's ``operator[]`` is only
|
|
||||||
required to return something convertible to its ``value_type``.
|
|
||||||
Requiring that it return an lvalue would rule out currently-legal
|
|
||||||
random-access iterators which hold the referenced value in a data
|
|
||||||
member (e.g. `counting_iterator`_), because ``*(p+n)`` is a reference
|
|
||||||
into the temporary iterator ``p+n``, which is destroyed when
|
|
||||||
``operator[]`` returns.
|
|
||||||
|
|
||||||
Writable iterators built with ``iterator_facade`` implement the
|
|
||||||
semantics required by the preferred resolution to `issue 299`_ and
|
|
||||||
adopted by proposal `n1477`_: the result of ``p[n]`` is a proxy object
|
|
||||||
containing a copy of ``p+n``, and ``p[n] = x`` is equivalent to ``*(p
|
|
||||||
+ n) = x``. This approach will work properly for any random-access
|
|
||||||
iterator regardless of the other details of its implementation. A
|
|
||||||
user who knows more about the implementation of her iterator is free
|
|
||||||
to implement an ``operator[]`` which returns an lvalue in the derived
|
|
||||||
iterator class; it will hide the one supplied by ``iterator_facade``
|
|
||||||
from clients of her iterator.
|
|
||||||
|
|
||||||
.. _issue 299: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#299
|
|
||||||
|
|
||||||
.. _`operator arrow`:
|
|
||||||
|
|
||||||
``operator->``
|
|
||||||
==============
|
|
||||||
|
|
||||||
The ``reference`` type of a readable iterator (and today's input
|
|
||||||
iterator) need not in fact be a reference, so long as it is
|
|
||||||
convertible to the iterator's ``value_type``. When the ``value_type``
|
|
||||||
is a class, however, it must still be possible to access members
|
|
||||||
through ``operator->``. Therefore, an iterator whose ``reference``
|
|
||||||
type is not in fact a reference must return a proxy containing a copy
|
|
||||||
of the referenced value from its ``operator->``.
|
|
||||||
|
|
||||||
This proposal does not explicitly specify the return type for
|
|
||||||
``operator->`` and ``operator[]``. Instead it requires each
|
|
||||||
``iterator_facade`` instantiation to meet the requirements of its
|
|
||||||
``iterator_category``.
|
|
||||||
|
|
||||||
Iterator Adaptor
|
Iterator Adaptor
|
||||||
================
|
================
|
||||||
|
|
||||||
The ``iterator_adaptor`` class template adapts some ``Base`` [#base]_
|
.. include:: iterator_adaptor_body.rst
|
||||||
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, ``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
|
|
||||||
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`` creates a class derived from an
|
|
||||||
instantiation of ``iterator_adaptor`` and then selectively
|
|
||||||
redefines some of the core member functions described in the table
|
|
||||||
above. The ``Base`` type need not meet the full requirements for an
|
|
||||||
iterator. It need only support the operations used by the core
|
|
||||||
interface functions of ``iterator_adaptor`` that have not been
|
|
||||||
redefined in the user's derived class.
|
|
||||||
|
|
||||||
Several of the template parameters of ``iterator_adaptor`` default to
|
|
||||||
``use_default``. This allows the user to make use of a default
|
|
||||||
parameter even when the user wants to specify a parameter later in the
|
|
||||||
parameter list. Also, the defaults for the corresponding associated
|
|
||||||
types are fairly complicated, so metaprogramming is required to
|
|
||||||
compute them, and ``use_default`` can help to simplify the
|
|
||||||
implementation. Finally, ``use_default`` is not left unspecified
|
|
||||||
because specification helps to highlight that the ``Reference``
|
|
||||||
template parameter may not always be identical to the iterator's
|
|
||||||
``reference`` type, and will keep users making mistakes based on that
|
|
||||||
assumption.
|
|
||||||
|
|
||||||
Specialized Adaptors
|
Specialized Adaptors
|
||||||
====================
|
====================
|
||||||
@ -488,296 +287,12 @@ Header ``<iterator_helper>`` synopsis [lib.iterator.helper.synopsis]
|
|||||||
Iterator facade [lib.iterator.facade]
|
Iterator facade [lib.iterator.facade]
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
``iterator_facade`` is a base class template which implements the
|
..include:: iterator_facade_abstract.rst
|
||||||
interface of standard iterators in terms of a few core functions
|
|
||||||
and associated types, to be supplied by a derived iterator class.
|
|
||||||
|
|
||||||
Class template ``iterator_facade``
|
Class template ``iterator_facade``
|
||||||
----------------------------------
|
----------------------------------
|
||||||
|
|
||||||
.. parsed-literal::
|
..include:: iterator_facade_ref.rst
|
||||||
|
|
||||||
template <
|
|
||||||
class Derived
|
|
||||||
, class Value
|
|
||||||
, class AccessCategory
|
|
||||||
, class TraversalCategory
|
|
||||||
, class Reference = /* see below__ \*/
|
|
||||||
, class Difference = ptrdiff_t
|
|
||||||
>
|
|
||||||
class iterator_facade {
|
|
||||||
public:
|
|
||||||
typedef remove_cv<Value>::type value_type;
|
|
||||||
typedef Reference reference;
|
|
||||||
typedef /* see `description of operator->`__ \*/ pointer;
|
|
||||||
typedef Difference difference_type;
|
|
||||||
typedef iterator_tag<AccessCategory, TraversalCategory> iterator_category;
|
|
||||||
|
|
||||||
reference operator\*() const;
|
|
||||||
/* see below__ \*/ operator->() const;
|
|
||||||
/* see below__ \*/ operator[](difference_type n) const;
|
|
||||||
Derived& operator++();
|
|
||||||
Derived operator++(int);
|
|
||||||
Derived& operator--();
|
|
||||||
Derived operator--(int);
|
|
||||||
Derived& operator+=(difference_type n);
|
|
||||||
Derived& operator-=(difference_type n);
|
|
||||||
Derived operator-(difference_type n) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Comparison operators
|
|
||||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
|
||||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
|
||||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type // exposition
|
|
||||||
operator ==(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
|
||||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
|
||||||
|
|
||||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
|
||||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
|
||||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
|
||||||
operator !=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
|
||||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
|
||||||
|
|
||||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
|
||||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
|
||||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
|
||||||
operator <(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
|
||||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
|
||||||
|
|
||||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
|
||||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
|
||||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
|
||||||
operator <=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
|
||||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
|
||||||
|
|
||||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
|
||||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
|
||||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
|
||||||
operator >(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
|
||||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
|
||||||
|
|
||||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
|
||||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
|
||||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
|
||||||
operator >=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
|
||||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
|
||||||
|
|
||||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
|
||||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
|
||||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
|
||||||
operator >=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
|
||||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
|
||||||
|
|
||||||
// Iterator difference
|
|
||||||
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
|
||||||
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
|
||||||
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
|
||||||
operator -(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
|
||||||
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
|
||||||
|
|
||||||
// Iterator addition
|
|
||||||
template <class Derived, class V, class AC, class TC, class R, class D>
|
|
||||||
Derived operator+ (iterator_facade<Derived, V, AC, TC, R, D> const&,
|
|
||||||
typename Derived::difference_type n)
|
|
||||||
|
|
||||||
|
|
||||||
__ `iterator facade requirements`_
|
|
||||||
|
|
||||||
__ `operator arrow`_
|
|
||||||
|
|
||||||
__ `operator arrow`_
|
|
||||||
|
|
||||||
__ brackets_
|
|
||||||
|
|
||||||
[*Note:* The ``enable_if_interoperable`` template used above is for exposition
|
|
||||||
purposes. The member operators should be only be in an overload set
|
|
||||||
provided the derived types ``Dr1`` and ``Dr2`` are interoperable, by
|
|
||||||
which we mean they are convertible to each other. The
|
|
||||||
``enable_if_interoperable`` approach uses SFINAE to take the operators
|
|
||||||
out of the overload set when the types are not interoperable.]
|
|
||||||
|
|
||||||
|
|
||||||
.. we need a new label here because the presence of markup in the
|
|
||||||
title prevents an automatic link from being generated
|
|
||||||
|
|
||||||
.. _iterator facade requirements:
|
|
||||||
|
|
||||||
``iterator_facade`` requirements
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
The ``Derived`` template parameter must be a class derived from
|
|
||||||
``iterator_facade``.
|
|
||||||
|
|
||||||
The default for the ``Reference`` parameter is ``Value&`` if the
|
|
||||||
access category for ``iterator_facade`` is implicitly convertible to
|
|
||||||
``writable_iterator_tag``, and ``const Value&`` otherwise.
|
|
||||||
|
|
||||||
The following table describes the other requirements on the
|
|
||||||
``Derived`` parameter. Depending on the resulting iterator's
|
|
||||||
``iterator_category``, a subset of the expressions listed in the table
|
|
||||||
are required to be valid. The operations in the first column must be
|
|
||||||
accessible to member functions of class ``iterator_core_access``.
|
|
||||||
|
|
||||||
In the table below, ``X`` is the derived iterator type, ``a`` is an
|
|
||||||
object of type ``X``, ``b`` and ``c`` are objects of type ``const X``,
|
|
||||||
``n`` is an object of ``X::difference_type``, ``y`` is a constant
|
|
||||||
object of a single pass iterator type interoperable with X, and ``z``
|
|
||||||
is a constant object of a random access traversal iterator type
|
|
||||||
interoperable with ``X``.
|
|
||||||
|
|
||||||
+--------------------+-------------------+-------------------------------------+---------------------------+
|
|
||||||
|Expression |Return Type |Assertion/Note |Required to implement |
|
|
||||||
| | | |Iterator Concept(s) |
|
|
||||||
+====================+===================+=====================================+===========================+
|
|
||||||
|``c.dereference()`` |``X::reference`` | |Readable Iterator, Writable|
|
|
||||||
| | | |Iterator |
|
|
||||||
+--------------------+-------------------+-------------------------------------+---------------------------+
|
|
||||||
|``c.equal(b)`` |convertible to bool|true iff ``b`` and ``c`` are |Single Pass Iterator |
|
|
||||||
| | |equivalent. | |
|
|
||||||
+--------------------+-------------------+-------------------------------------+---------------------------+
|
|
||||||
|``c.equal(y)`` |convertible to bool|true iff ``c`` and ``y`` refer to the|Single Pass Iterator |
|
|
||||||
| | |same position. Implements ``c == y``| |
|
|
||||||
| | |and ``c != y``. | |
|
|
||||||
+--------------------+-------------------+-------------------------------------+---------------------------+
|
|
||||||
|``a.advance(n)`` |unused | |Random Access Traversal |
|
|
||||||
| | | |Iterator |
|
|
||||||
+--------------------+-------------------+-------------------------------------+---------------------------+
|
|
||||||
|``a.increment()`` |unused | |Incrementable Iterator |
|
|
||||||
+--------------------+-------------------+-------------------------------------+---------------------------+
|
|
||||||
|``a.decrement()`` |unused | |Bidirectional Traversal |
|
|
||||||
| | | |Iterator |
|
|
||||||
+--------------------+-------------------+-------------------------------------+---------------------------+
|
|
||||||
|``c.distance_to(b)``|convertible to |equivalent to ``distance(c, b)`` |Random Access Traversal |
|
|
||||||
| |X::difference_type | |Iterator |
|
|
||||||
+--------------------+-------------------+-------------------------------------+---------------------------+
|
|
||||||
|``c.distance_to(z)``|convertible to |equivalent to ``distance(c, z)``. |Random Access Traversal |
|
|
||||||
| |X::difference_type |Implements ``c - z``, ``c < z``, ``c |Iterator |
|
|
||||||
| | |<= z``, ``c > z``, and ``c >= c``. | |
|
|
||||||
+--------------------+-------------------+-------------------------------------+---------------------------+
|
|
||||||
|
|
||||||
.. We should explain more about how the
|
|
||||||
functions in the interface of iterator_facade
|
|
||||||
are there conditionally. -JGS
|
|
||||||
|
|
||||||
|
|
||||||
``iterator_facade`` operations
|
|
||||||
------------------------------
|
|
||||||
|
|
||||||
The operations in this section are described in terms of operations on
|
|
||||||
the core interface of ``Derived`` which may be inaccessible
|
|
||||||
(i.e. private). The implementation should access these operations
|
|
||||||
through member functions of class ``iterator_core_access``.
|
|
||||||
|
|
||||||
``reference operator*() const;``
|
|
||||||
|
|
||||||
:Returns: ``static_cast<Derived const*>(this)->dereference()``
|
|
||||||
|
|
||||||
``operator->() const;`` (see below__)
|
|
||||||
|
|
||||||
__ `operator arrow`_
|
|
||||||
|
|
||||||
:Returns: If ``X::reference`` is a reference type, returns an object
|
|
||||||
of type ``X::pointer`` equal to::
|
|
||||||
|
|
||||||
&static_cast<Derived const*>(this)->dereference()
|
|
||||||
|
|
||||||
Otherwise returns an object of unspecified type such that, given an
|
|
||||||
object ``a`` of type ``X``, ``a->m`` is equivalent to ``(w = *a,
|
|
||||||
w.m)`` for some temporary object ``w`` of type ``X::value_type``.
|
|
||||||
|
|
||||||
The type ``X::pointer`` is ``Value*`` if the access category for
|
|
||||||
``X`` is implicitly convertible to ``writable_iterator_tag``, and
|
|
||||||
``Value const*`` otherwise.
|
|
||||||
|
|
||||||
|
|
||||||
.. _brackets:
|
|
||||||
|
|
||||||
*unspecified* ``operator[](difference_type n) const;``
|
|
||||||
|
|
||||||
:Returns: an object convertible to ``X::reference`` and holding a copy
|
|
||||||
*p* of ``a+n`` such that, for a constant object ``v`` of type
|
|
||||||
``X::value_type``, ``X::reference(a[n] = v)`` is equivalent
|
|
||||||
to ``p = v``.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
``Derived& operator++();``
|
|
||||||
|
|
||||||
:Effects:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
static_cast<Derived*>(this)->increment();
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
.. I realize that the committee is moving away from specifying things
|
|
||||||
like this in terms of code, but I worried about the imprecision of
|
|
||||||
saying that a core interface function is invoked without describing
|
|
||||||
the downcast. An alternative to what I did would be to mention it
|
|
||||||
above where we talk about accessibility.
|
|
||||||
|
|
||||||
|
|
||||||
``Derived operator++(int);``
|
|
||||||
|
|
||||||
:Effects:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
Derived tmp(static_cast<Derived const*>(this));
|
|
||||||
++*this;
|
|
||||||
return tmp;
|
|
||||||
|
|
||||||
|
|
||||||
``Derived& operator--();``
|
|
||||||
|
|
||||||
:Effects:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
static_cast<Derived*>(this)->decrement();
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
|
|
||||||
``Derived operator--(int);``
|
|
||||||
|
|
||||||
:Effects:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
Derived tmp(static_cast<Derived const*>(this));
|
|
||||||
--*this;
|
|
||||||
return tmp;
|
|
||||||
|
|
||||||
|
|
||||||
``Derived& operator+=(difference_type n);``
|
|
||||||
|
|
||||||
:Effects:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
static_cast<Derived*>(this)->advance(n);
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
|
|
||||||
``Derived& operator-=(difference_type n);``
|
|
||||||
|
|
||||||
:Effects:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
static_cast<Derived*>(this)->advance(-n);
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
|
|
||||||
``Derived operator-(difference_type n) const;``
|
|
||||||
|
|
||||||
:Effects:
|
|
||||||
|
|
||||||
Derived tmp(static_cast<Derived const*>(this));
|
|
||||||
return tmp -= n;
|
|
||||||
|
|
||||||
:Returns: ``static_cast<Derived const*>(this)->advance(-n);``
|
|
||||||
|
|
||||||
|
|
||||||
Iterator adaptor [lib.iterator.adaptor]
|
Iterator adaptor [lib.iterator.adaptor]
|
||||||
=======================================
|
=======================================
|
||||||
@ -1618,9 +1133,6 @@ and Incrementable Iterator concepts.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. [Cop95] [Coplien, 1995] Coplien, J., Curiously Recurring Template
|
|
||||||
Patterns, C++ Report, February 1995, pp. 24-27.
|
|
||||||
|
|
||||||
..
|
..
|
||||||
LocalWords: Abrahams Siek Witt istream ostream iter MTL strided interoperate
|
LocalWords: Abrahams Siek Witt istream ostream iter MTL strided interoperate
|
||||||
LocalWords: CRTP metafunctions inlining lvalue JGS incrementable BGL LEDA cv
|
LocalWords: CRTP metafunctions inlining lvalue JGS incrementable BGL LEDA cv
|
||||||
|
@ -3,13 +3,13 @@
|
|||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
<meta name="generator" content="Docutils 0.3.0: http://docutils.sourceforge.net/" />
|
<meta name="generator" content="Docutils 0.2.8: http://docutils.sourceforge.net/" />
|
||||||
<title>The Boost Iterator Library </title>
|
<title>The Boost Iterator Library Boost</title>
|
||||||
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
|
<link rel="stylesheet" href="default.css" type="text/css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="document" id="the-boost-iterator-library-logo">
|
<div class="document" id="the-boost-iterator-library-logo">
|
||||||
<h1 class="title">The Boost Iterator Library <a class="reference" href="../../../index.htm"><img alt="" src="../../../c++boost.gif" /></a></h1>
|
<h1 class="title">The Boost Iterator Library <a class="reference" href="../../../index.htm"><img alt="Boost" src="../../../c++boost.gif" /></a></h1>
|
||||||
<hr />
|
<hr />
|
||||||
<table class="field-list" frame="void" rules="none">
|
<table class="field-list" frame="void" rules="none">
|
||||||
<col class="field-name" />
|
<col class="field-name" />
|
||||||
@ -33,10 +33,12 @@ Railway Operation and Construction</a></td>
|
|||||||
<col class="field-name" />
|
<col class="field-name" />
|
||||||
<col class="field-body" />
|
<col class="field-body" />
|
||||||
<tbody valign="top">
|
<tbody valign="top">
|
||||||
<tr class="field"><th class="field-name">Abstract:</th><td class="field-body">The Boost Iterator Library is a system of <a class="reference" href="../../more/generic_programming.html">concepts</a> which
|
<tr class="field"><th class="field-name">Abstract:</th><td class="field-body">The Boost Iterator Library contains two parts. The first
|
||||||
extend the C++ standard iterator definition and a framework
|
is a system of <a class="reference" href="../../more/generic_programming.html">concepts</a> which extend the C++ standard
|
||||||
|
iterator requirements. The second is a framework
|
||||||
of components for building iterators based on these
|
of components for building iterators based on these
|
||||||
extended concepts. The extended iterator concepts have
|
extended concepts and includes several useful iterator
|
||||||
|
adaptors. The extended iterator concepts have
|
||||||
been carefully designed so that new-style iterators will be
|
been carefully designed so that new-style iterators will be
|
||||||
compatible with old-style algorithms, though algorithms may
|
compatible with old-style algorithms, though algorithms may
|
||||||
need to be updated if they want to take full advantage of
|
need to be updated if they want to take full advantage of
|
||||||
@ -175,11 +177,5 @@ LocalWords: incrementable xxx min prev inplace png oldeqnew AccessTag struct
|
|||||||
LocalWords: TraversalTag typename lvalues DWA Hmm JGS -->
|
LocalWords: TraversalTag typename lvalues DWA Hmm JGS -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr class="footer"/>
|
|
||||||
<div class="footer">
|
|
||||||
<a class="reference" href="index.rst">View document source</a>.
|
|
||||||
Generated on: 2003-07-29 22:24 UTC.
|
|
||||||
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
|
|
||||||
</div>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
+++++++++++++++++++++++++++++++++++++++++++++++++
|
+++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
.. |(logo)| image:: ../../../c++boost.gif
|
.. |(logo)| image:: ../../../c++boost.gif
|
||||||
:alt:
|
:alt: Boost
|
||||||
|
|
||||||
__ ../../../index.htm
|
__ ../../../index.htm
|
||||||
|
|
||||||
@ -23,10 +23,12 @@ __ ../../../index.htm
|
|||||||
.. _`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: The Boost Iterator Library is a system of concepts_ which
|
:Abstract: The Boost Iterator Library contains two parts. The first
|
||||||
extend the C++ standard iterator definition and a framework
|
is a system of concepts_ which extend the C++ standard
|
||||||
|
iterator requirements. The second is a framework
|
||||||
of components for building iterators based on these
|
of components for building iterators based on these
|
||||||
extended concepts. The extended iterator concepts have
|
extended concepts and includes several useful iterator
|
||||||
|
adaptors. The extended iterator concepts have
|
||||||
been carefully designed so that new-style iterators will be
|
been carefully designed so that new-style iterators will be
|
||||||
compatible with old-style algorithms, though algorithms may
|
compatible with old-style algorithms, though algorithms may
|
||||||
need to be updated if they want to take full advantage of
|
need to be updated if they want to take full advantage of
|
||||||
|
18
doc/iterator_adaptor.rst
Normal file
18
doc/iterator_adaptor.rst
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
+++++++++++++++++
|
||||||
|
Iterator Adaptor
|
||||||
|
+++++++++++++++++
|
||||||
|
|
||||||
|
:Author: David Abrahams, Jeremy Siek, Thomas Witt
|
||||||
|
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
|
||||||
|
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||||
|
Lab`_, University of Hanover `Institute for Transport
|
||||||
|
Railway Operation and Construction`_
|
||||||
|
:date: $Date$
|
||||||
|
:copyright: Copyright Dave Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
|
||||||
|
|
||||||
|
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||||
|
.. _`Open Systems Lab`: http://www.osl.iu.edu
|
||||||
|
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
|
||||||
|
|
||||||
|
.. include:: iterator_adaptor_body.rst
|
||||||
|
|
32
doc/iterator_adaptor_body.rst
Normal file
32
doc/iterator_adaptor_body.rst
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
The ``iterator_adaptor`` class template adapts some ``Base`` [#base]_
|
||||||
|
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, ``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
|
||||||
|
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`` creates a class derived from an
|
||||||
|
instantiation of ``iterator_adaptor`` and then selectively
|
||||||
|
redefines some of the core member functions described in the table
|
||||||
|
above. The ``Base`` type need not meet the full requirements for an
|
||||||
|
iterator. It need only support the operations used by the core
|
||||||
|
interface functions of ``iterator_adaptor`` that have not been
|
||||||
|
redefined in the user's derived class.
|
||||||
|
|
||||||
|
Several of the template parameters of ``iterator_adaptor`` default to
|
||||||
|
``use_default``. This allows the user to make use of a default
|
||||||
|
parameter even when the user wants to specify a parameter later in the
|
||||||
|
parameter list. Also, the defaults for the corresponding associated
|
||||||
|
types are fairly complicated, so metaprogramming is required to
|
||||||
|
compute them, and ``use_default`` can help to simplify the
|
||||||
|
implementation. Finally, ``use_default`` is not left unspecified
|
||||||
|
because specification helps to highlight that the ``Reference``
|
||||||
|
template parameter may not always be identical to the iterator's
|
||||||
|
``reference`` type, and will keep users making mistakes based on that
|
||||||
|
assumption.
|
||||||
|
|
33
doc/iterator_facade.rst
Normal file
33
doc/iterator_facade.rst
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
++++++++++++++++
|
||||||
|
Iterator Facade
|
||||||
|
++++++++++++++++
|
||||||
|
|
||||||
|
:Author: David Abrahams, Jeremy Siek, Thomas Witt
|
||||||
|
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
|
||||||
|
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||||
|
Lab`_, University of Hanover `Institute for Transport
|
||||||
|
Railway Operation and Construction`_
|
||||||
|
:date: $Date$
|
||||||
|
:copyright: Copyright Dave Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
|
||||||
|
|
||||||
|
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||||
|
.. _`Open Systems Lab`: http://www.osl.iu.edu
|
||||||
|
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
|
||||||
|
|
||||||
|
:abstract:
|
||||||
|
|
||||||
|
.. include:: iterator_facade_abstract.rst
|
||||||
|
|
||||||
|
.. contents:: Table of Contents
|
||||||
|
|
||||||
|
|
||||||
|
Motivation
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. include:: iterator_facade_body.rst
|
||||||
|
|
||||||
|
|
||||||
|
Reference
|
||||||
|
---------
|
||||||
|
|
||||||
|
.. include:: iterator_facade_ref.rst
|
4
doc/iterator_facade_abstract.rst
Normal file
4
doc/iterator_facade_abstract.rst
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
``iterator_facade`` is a base class template which implements the
|
||||||
|
interface of standard iterators in terms of a few core functions
|
||||||
|
and associated types, to be supplied by a derived iterator class.
|
||||||
|
|
180
doc/iterator_facade_body.rst
Normal file
180
doc/iterator_facade_body.rst
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
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
|
||||||
|
* incrementing
|
||||||
|
* decrementing
|
||||||
|
* equality comparison
|
||||||
|
* random-access motion
|
||||||
|
* distance measurement
|
||||||
|
|
||||||
|
In addition to the behaviors listed above, the core interface elements
|
||||||
|
include the associated types exposed through iterator traits:
|
||||||
|
``value_type``, ``reference``, ``difference_type``, and
|
||||||
|
``iterator_category``.
|
||||||
|
|
||||||
|
Iterator facade uses the Curiously Recurring Template Pattern (CRTP)
|
||||||
|
[Cop95]_ so that the user can specify the behavior of
|
||||||
|
``iterator_facade`` in a derived class. Former designs used policy
|
||||||
|
objects to specify the behavior. ``iterator_facade`` does not use policy
|
||||||
|
objects for several reasons:
|
||||||
|
|
||||||
|
1. the creation and eventual copying of the policy object may create
|
||||||
|
overhead that can be avoided with the current approach.
|
||||||
|
|
||||||
|
2. The policy object approach does not allow for custom constructors
|
||||||
|
on the created iterator types, an essential feature if
|
||||||
|
``iterator_facade`` should be used in other library
|
||||||
|
implementations.
|
||||||
|
|
||||||
|
3. Without the use of CRTP, the standard requirement that an
|
||||||
|
iterator's ``operator++`` returns the iterator type itself means
|
||||||
|
that all iterators generated by ``iterator_facade`` would be
|
||||||
|
instantiations of ``iterator_facade``. Cumbersome type generator
|
||||||
|
metafunctions would be needed to build new parameterized
|
||||||
|
iterators, and a separate ``iterator_adaptor`` layer would be
|
||||||
|
impossible.
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-----
|
||||||
|
|
||||||
|
The user of ``iterator_facade`` derives his iterator class from an
|
||||||
|
instantiation of ``iterator_facade`` which takes the derived iterator
|
||||||
|
class as the first template parameter. The order of the other
|
||||||
|
template parameters to ``iterator_facade`` have been carefully chosen
|
||||||
|
to take advantage of useful defaults. For example, when defining a
|
||||||
|
constant lvalue iterator, the user can pass a const-qualified version
|
||||||
|
of the iterator's ``value_type`` as ``iterator_facade``\ 's ``Value``
|
||||||
|
parameter and omit the ``Reference`` parameter which follows.
|
||||||
|
|
||||||
|
The derived iterator class must define member functions implementing
|
||||||
|
the iterator's core behaviors. The following table describes
|
||||||
|
expressions which are required to be valid depending on the category
|
||||||
|
of the derived iterator type. These member functions are described
|
||||||
|
briefly below and in more detail in the iterator facade
|
||||||
|
requirements.
|
||||||
|
|
||||||
|
+------------------------+-------------------------------+
|
||||||
|
|Expression |Effects |
|
||||||
|
+========================+===============================+
|
||||||
|
|``i.dereference()`` |Access the value referred to |
|
||||||
|
+------------------------+-------------------------------+
|
||||||
|
|``i.equal(j)`` |Compare for equality with ``j``|
|
||||||
|
+------------------------+-------------------------------+
|
||||||
|
|``i.increment()`` |Advance by one position |
|
||||||
|
+------------------------+-------------------------------+
|
||||||
|
|``i.decrement()`` |Retreat by one position |
|
||||||
|
+------------------------+-------------------------------+
|
||||||
|
|``i.advance(n)`` |Advance by ``n`` positions |
|
||||||
|
+------------------------+-------------------------------+
|
||||||
|
|``i.distance_to(j)`` |Measure the distance to ``j`` |
|
||||||
|
+------------------------+-------------------------------+
|
||||||
|
|
||||||
|
.. Should we add a comment that a zero overhead implementation of iterator_facade
|
||||||
|
is possible with proper inlining?
|
||||||
|
|
||||||
|
In addition to implementing the core interface functions, an iterator
|
||||||
|
derived from ``iterator_facade`` typically defines several
|
||||||
|
constructors. To model any of the standard iterator concepts, the
|
||||||
|
iterator must at least have a copy constructor. Also, if the iterator
|
||||||
|
type ``X`` is meant to be automatically interoperate with another
|
||||||
|
iterator type ``Y`` (as with constant and mutable iterators) then
|
||||||
|
there must be an implicit conversion from ``X`` to ``Y`` or from ``Y``
|
||||||
|
to ``X`` (but not both), typically implemented as a conversion
|
||||||
|
constructor. Finally, if the iterator is to model Forward Traversal
|
||||||
|
Iterator or a more-refined iterator concept, a default constructor is
|
||||||
|
required.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Iterator Core Access
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
``iterator_facade`` and the operator implementations need to be able
|
||||||
|
to access the core member functions in the derived class. Making the
|
||||||
|
core member functions public would expose an implementation detail to
|
||||||
|
the user. The design used here ensures that implementation details do
|
||||||
|
not appear in the public interface of the derived iterator type.
|
||||||
|
|
||||||
|
Preventing direct access to the core member functions has two
|
||||||
|
advantages. First, there is no possibility for the user to accidently
|
||||||
|
use a member function of the iterator when a member of the value_type
|
||||||
|
was intended. This has been an issue with smart pointer
|
||||||
|
implementations in the past. The second and main advantage is that
|
||||||
|
library implementers can freely exchange a hand-rolled iterator
|
||||||
|
implementation for one based on ``iterator_facade`` without fear of
|
||||||
|
breaking code that was accessing the public core member functions
|
||||||
|
directly.
|
||||||
|
|
||||||
|
In a naive implementation, keeping the derived class' core member
|
||||||
|
functions private would require it to grant friendship to
|
||||||
|
``iterator_facade`` and each of the seven operators. In order to
|
||||||
|
reduce the burden of limiting access, ``iterator_core_access`` is
|
||||||
|
provided, a class that acts as a gateway to the core member functions
|
||||||
|
in the derived iterator class. The author of the derived class only
|
||||||
|
needs to grant friendship to ``iterator_core_access`` to make his core
|
||||||
|
member functions available to the library.
|
||||||
|
|
||||||
|
.. This is no long uptodate -thw
|
||||||
|
.. Yes it is; I made sure of it! -DWA
|
||||||
|
|
||||||
|
``iterator_core_access`` will be typically implemented as an empty
|
||||||
|
class containing only private static member functions which invoke the
|
||||||
|
iterator core member functions. There is, however, no need to
|
||||||
|
standardize the gateway protocol. Note that even if
|
||||||
|
``iterator_core_access`` used public member functions it would not
|
||||||
|
open a safety loophole, as every core member function preserves the
|
||||||
|
invariants of the iterator.
|
||||||
|
|
||||||
|
``operator[]``
|
||||||
|
--------------
|
||||||
|
|
||||||
|
The indexing operator for a generalized iterator presents special
|
||||||
|
challenges. A random access iterator's ``operator[]`` is only
|
||||||
|
required to return something convertible to its ``value_type``.
|
||||||
|
Requiring that it return an lvalue would rule out currently-legal
|
||||||
|
random-access iterators which hold the referenced value in a data
|
||||||
|
member (e.g. `counting_iterator`__), because ``*(p+n)`` is a reference
|
||||||
|
into the temporary iterator ``p+n``, which is destroyed when
|
||||||
|
``operator[]`` returns.
|
||||||
|
|
||||||
|
__ counting_iterator.html
|
||||||
|
|
||||||
|
Writable iterators built with ``iterator_facade`` implement the
|
||||||
|
semantics required by the preferred resolution to `issue 299`_ and
|
||||||
|
adopted by proposal `n1477`_: the result of ``p[n]`` is a proxy object
|
||||||
|
containing a copy of ``p+n``, and ``p[n] = x`` is equivalent to ``*(p
|
||||||
|
+ n) = x``. This approach will work properly for any random-access
|
||||||
|
iterator regardless of the other details of its implementation. A
|
||||||
|
user who knows more about the implementation of her iterator is free
|
||||||
|
to implement an ``operator[]`` which returns an lvalue in the derived
|
||||||
|
iterator class; it will hide the one supplied by ``iterator_facade``
|
||||||
|
from clients of her iterator.
|
||||||
|
|
||||||
|
.. _`n1477`: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1477.html
|
||||||
|
|
||||||
|
.. _issue 299: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#299
|
||||||
|
|
||||||
|
.. _`operator arrow`:
|
||||||
|
|
||||||
|
|
||||||
|
``operator->``
|
||||||
|
--------------
|
||||||
|
|
||||||
|
The ``reference`` type of a readable iterator (and today's input
|
||||||
|
iterator) need not in fact be a reference, so long as it is
|
||||||
|
convertible to the iterator's ``value_type``. When the ``value_type``
|
||||||
|
is a class, however, it must still be possible to access members
|
||||||
|
through ``operator->``. Therefore, an iterator whose ``reference``
|
||||||
|
type is not in fact a reference must return a proxy containing a copy
|
||||||
|
of the referenced value from its ``operator->``.
|
||||||
|
|
||||||
|
The return type for ``operator->`` and ``operator[]`` is not
|
||||||
|
explicitly specified. Instead it requires each ``iterator_facade``
|
||||||
|
instantiation to meet the requirements of its ``iterator_category``.
|
||||||
|
|
||||||
|
|
||||||
|
.. [Cop95] [Coplien, 1995] Coplien, J., Curiously Recurring Template
|
||||||
|
Patterns, C++ Report, February 1995, pp. 24-27.
|
||||||
|
|
284
doc/iterator_facade_ref.rst
Normal file
284
doc/iterator_facade_ref.rst
Normal file
@ -0,0 +1,284 @@
|
|||||||
|
.. parsed-literal::
|
||||||
|
|
||||||
|
template <
|
||||||
|
class Derived
|
||||||
|
, class Value
|
||||||
|
, class AccessCategory
|
||||||
|
, class TraversalCategory
|
||||||
|
, class Reference = /* see below__ \*/
|
||||||
|
, class Difference = ptrdiff_t
|
||||||
|
>
|
||||||
|
class iterator_facade {
|
||||||
|
public:
|
||||||
|
typedef remove_cv<Value>::type value_type;
|
||||||
|
typedef Reference reference;
|
||||||
|
typedef /* see `description of operator->`__ \*/ pointer;
|
||||||
|
typedef Difference difference_type;
|
||||||
|
typedef iterator_tag<AccessCategory, TraversalCategory> iterator_category;
|
||||||
|
|
||||||
|
reference operator\*() const;
|
||||||
|
/* see below__ \*/ operator->() const;
|
||||||
|
/* see below__ \*/ operator[](difference_type n) const;
|
||||||
|
Derived& operator++();
|
||||||
|
Derived operator++(int);
|
||||||
|
Derived& operator--();
|
||||||
|
Derived operator--(int);
|
||||||
|
Derived& operator+=(difference_type n);
|
||||||
|
Derived& operator-=(difference_type n);
|
||||||
|
Derived operator-(difference_type n) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Comparison operators
|
||||||
|
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||||
|
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||||
|
typename enable_if_interoperable<Dr1, Dr2, bool>::type // exposition
|
||||||
|
operator ==(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||||
|
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||||
|
|
||||||
|
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||||
|
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||||
|
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
||||||
|
operator !=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||||
|
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||||
|
|
||||||
|
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||||
|
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||||
|
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
||||||
|
operator <(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||||
|
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||||
|
|
||||||
|
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||||
|
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||||
|
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
||||||
|
operator <=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||||
|
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||||
|
|
||||||
|
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||||
|
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||||
|
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
||||||
|
operator >(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||||
|
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||||
|
|
||||||
|
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||||
|
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||||
|
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
||||||
|
operator >=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||||
|
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||||
|
|
||||||
|
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||||
|
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||||
|
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
||||||
|
operator >=(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||||
|
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||||
|
|
||||||
|
// Iterator difference
|
||||||
|
template <class Dr1, class V1, class AC1, class TC1, class R1, class D1,
|
||||||
|
class Dr2, class V2, class AC2, class TC2, class R2, class D2>
|
||||||
|
typename enable_if_interoperable<Dr1, Dr2, bool>::type
|
||||||
|
operator -(iterator_facade<Dr1, V1, AC1, TC1, R1, D1> const& lhs,
|
||||||
|
iterator_facade<Dr2, V2, AC2, TC2, R2, D2> const& rhs);
|
||||||
|
|
||||||
|
// Iterator addition
|
||||||
|
template <class Derived, class V, class AC, class TC, class R, class D>
|
||||||
|
Derived operator+ (iterator_facade<Derived, V, AC, TC, R, D> const&,
|
||||||
|
typename Derived::difference_type n)
|
||||||
|
|
||||||
|
|
||||||
|
__ `iterator facade requirements`_
|
||||||
|
|
||||||
|
__ `operator arrow`_
|
||||||
|
|
||||||
|
__ `operator arrow`_
|
||||||
|
|
||||||
|
__ brackets_
|
||||||
|
|
||||||
|
[*Note:* The ``enable_if_interoperable`` template used above is for exposition
|
||||||
|
purposes. The member operators should be only be in an overload set
|
||||||
|
provided the derived types ``Dr1`` and ``Dr2`` are interoperable, by
|
||||||
|
which we mean they are convertible to each other. The
|
||||||
|
``enable_if_interoperable`` approach uses SFINAE to take the operators
|
||||||
|
out of the overload set when the types are not interoperable.]
|
||||||
|
|
||||||
|
|
||||||
|
.. we need a new label here because the presence of markup in the
|
||||||
|
title prevents an automatic link from being generated
|
||||||
|
|
||||||
|
.. _iterator facade requirements:
|
||||||
|
|
||||||
|
``iterator_facade`` requirements
|
||||||
|
================================
|
||||||
|
|
||||||
|
The ``Derived`` template parameter must be a class derived from
|
||||||
|
``iterator_facade``.
|
||||||
|
|
||||||
|
The default for the ``Reference`` parameter is ``Value&`` if the
|
||||||
|
access category for ``iterator_facade`` is implicitly convertible to
|
||||||
|
``writable_iterator_tag``, and ``const Value&`` otherwise.
|
||||||
|
|
||||||
|
The following table describes the other requirements on the
|
||||||
|
``Derived`` parameter. Depending on the resulting iterator's
|
||||||
|
``iterator_category``, a subset of the expressions listed in the table
|
||||||
|
are required to be valid. The operations in the first column must be
|
||||||
|
accessible to member functions of class ``iterator_core_access``.
|
||||||
|
|
||||||
|
In the table below, ``X`` is the derived iterator type, ``a`` is an
|
||||||
|
object of type ``X``, ``b`` and ``c`` are objects of type ``const X``,
|
||||||
|
``n`` is an object of ``X::difference_type``, ``y`` is a constant
|
||||||
|
object of a single pass iterator type interoperable with X, and ``z``
|
||||||
|
is a constant object of a random access traversal iterator type
|
||||||
|
interoperable with ``X``.
|
||||||
|
|
||||||
|
+--------------------+-------------------+-------------------------------------+---------------------------+
|
||||||
|
|Expression |Return Type |Assertion/Note |Required to implement |
|
||||||
|
| | | |Iterator Concept(s) |
|
||||||
|
+====================+===================+=====================================+===========================+
|
||||||
|
|``c.dereference()`` |``X::reference`` | |Readable Iterator, Writable|
|
||||||
|
| | | |Iterator |
|
||||||
|
+--------------------+-------------------+-------------------------------------+---------------------------+
|
||||||
|
|``c.equal(b)`` |convertible to bool|true iff ``b`` and ``c`` are |Single Pass Iterator |
|
||||||
|
| | |equivalent. | |
|
||||||
|
+--------------------+-------------------+-------------------------------------+---------------------------+
|
||||||
|
|``c.equal(y)`` |convertible to bool|true iff ``c`` and ``y`` refer to the|Single Pass Iterator |
|
||||||
|
| | |same position. Implements ``c == y``| |
|
||||||
|
| | |and ``c != y``. | |
|
||||||
|
+--------------------+-------------------+-------------------------------------+---------------------------+
|
||||||
|
|``a.advance(n)`` |unused | |Random Access Traversal |
|
||||||
|
| | | |Iterator |
|
||||||
|
+--------------------+-------------------+-------------------------------------+---------------------------+
|
||||||
|
|``a.increment()`` |unused | |Incrementable Iterator |
|
||||||
|
+--------------------+-------------------+-------------------------------------+---------------------------+
|
||||||
|
|``a.decrement()`` |unused | |Bidirectional Traversal |
|
||||||
|
| | | |Iterator |
|
||||||
|
+--------------------+-------------------+-------------------------------------+---------------------------+
|
||||||
|
|``c.distance_to(b)``|convertible to |equivalent to ``distance(c, b)`` |Random Access Traversal |
|
||||||
|
| |X::difference_type | |Iterator |
|
||||||
|
+--------------------+-------------------+-------------------------------------+---------------------------+
|
||||||
|
|``c.distance_to(z)``|convertible to |equivalent to ``distance(c, z)``. |Random Access Traversal |
|
||||||
|
| |X::difference_type |Implements ``c - z``, ``c < z``, ``c |Iterator |
|
||||||
|
| | |<= z``, ``c > z``, and ``c >= c``. | |
|
||||||
|
+--------------------+-------------------+-------------------------------------+---------------------------+
|
||||||
|
|
||||||
|
.. We should explain more about how the
|
||||||
|
functions in the interface of iterator_facade
|
||||||
|
are there conditionally. -JGS
|
||||||
|
|
||||||
|
|
||||||
|
``iterator_facade`` operations
|
||||||
|
==============================
|
||||||
|
|
||||||
|
The operations in this section are described in terms of operations on
|
||||||
|
the core interface of ``Derived`` which may be inaccessible
|
||||||
|
(i.e. private). The implementation should access these operations
|
||||||
|
through member functions of class ``iterator_core_access``.
|
||||||
|
|
||||||
|
``reference operator*() const;``
|
||||||
|
|
||||||
|
:Returns: ``static_cast<Derived const*>(this)->dereference()``
|
||||||
|
|
||||||
|
``operator->() const;`` (see below__)
|
||||||
|
|
||||||
|
__ `operator arrow`_
|
||||||
|
|
||||||
|
:Returns: If ``X::reference`` is a reference type, returns an object
|
||||||
|
of type ``X::pointer`` equal to::
|
||||||
|
|
||||||
|
&static_cast<Derived const*>(this)->dereference()
|
||||||
|
|
||||||
|
Otherwise returns an object of unspecified type such that, given an
|
||||||
|
object ``a`` of type ``X``, ``a->m`` is equivalent to ``(w = *a,
|
||||||
|
w.m)`` for some temporary object ``w`` of type ``X::value_type``.
|
||||||
|
|
||||||
|
The type ``X::pointer`` is ``Value*`` if the access category for
|
||||||
|
``X`` is implicitly convertible to ``writable_iterator_tag``, and
|
||||||
|
``Value const*`` otherwise.
|
||||||
|
|
||||||
|
|
||||||
|
.. _brackets:
|
||||||
|
|
||||||
|
*unspecified* ``operator[](difference_type n) const;``
|
||||||
|
|
||||||
|
:Returns: an object convertible to ``X::reference`` and holding a copy
|
||||||
|
*p* of ``a+n`` such that, for a constant object ``v`` of type
|
||||||
|
``X::value_type``, ``X::reference(a[n] = v)`` is equivalent
|
||||||
|
to ``p = v``.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
``Derived& operator++();``
|
||||||
|
|
||||||
|
:Effects:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
static_cast<Derived*>(this)->increment();
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
.. I realize that the committee is moving away from specifying things
|
||||||
|
like this in terms of code, but I worried about the imprecision of
|
||||||
|
saying that a core interface function is invoked without describing
|
||||||
|
the downcast. An alternative to what I did would be to mention it
|
||||||
|
above where we talk about accessibility.
|
||||||
|
|
||||||
|
|
||||||
|
``Derived operator++(int);``
|
||||||
|
|
||||||
|
:Effects:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
Derived tmp(static_cast<Derived const*>(this));
|
||||||
|
++*this;
|
||||||
|
return tmp;
|
||||||
|
|
||||||
|
|
||||||
|
``Derived& operator--();``
|
||||||
|
|
||||||
|
:Effects:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
static_cast<Derived*>(this)->decrement();
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
|
||||||
|
``Derived operator--(int);``
|
||||||
|
|
||||||
|
:Effects:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
Derived tmp(static_cast<Derived const*>(this));
|
||||||
|
--*this;
|
||||||
|
return tmp;
|
||||||
|
|
||||||
|
|
||||||
|
``Derived& operator+=(difference_type n);``
|
||||||
|
|
||||||
|
:Effects:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
static_cast<Derived*>(this)->advance(n);
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
|
||||||
|
``Derived& operator-=(difference_type n);``
|
||||||
|
|
||||||
|
:Effects:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
static_cast<Derived*>(this)->advance(-n);
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
|
||||||
|
``Derived operator-(difference_type n) const;``
|
||||||
|
|
||||||
|
:Effects:
|
||||||
|
|
||||||
|
Derived tmp(static_cast<Derived const*>(this));
|
||||||
|
return tmp -= n;
|
||||||
|
|
||||||
|
:Returns: ``static_cast<Derived const*>(this)->advance(-n);``
|
||||||
|
|
||||||
|
|
@ -3,204 +3,13 @@
|
|||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
<meta name="generator" content="Docutils 0.2.10: http://docutils.sourceforge.net/" />
|
<meta name="generator" content="Docutils 0.2.8: http://docutils.sourceforge.net/" />
|
||||||
<title>New Iterator Concepts</title>
|
<title>New Iterator Concepts</title>
|
||||||
<meta name="author" content="David Abrahams, Jeremy Siek, Thomas Witt" />
|
<meta name="author" content="David Abrahams, Jeremy Siek, Thomas Witt" />
|
||||||
<meta name="organization" content="Boost Consulting, Indiana University Open Systems Lab, University of Hanover Institute for Transport Railway Operation and Construction" />
|
<meta name="organization" content="Boost Consulting, Indiana University Open Systems Lab, University of Hanover Institute for Transport Railway Operation and Construction" />
|
||||||
<meta name="date" content="2003-07-12" />
|
<meta name="date" content="2003-07-13" />
|
||||||
<meta name="copyright" content="Copyright Dave Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
|
<meta name="copyright" content="Copyright Dave Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
|
||||||
<style type="text/css"><!--
|
<link rel="stylesheet" href="default.css" type="text/css" />
|
||||||
|
|
||||||
/*
|
|
||||||
:Author: David Goodger
|
|
||||||
:Contact: goodger@users.sourceforge.net
|
|
||||||
:date: $Date$
|
|
||||||
:version: $Revision$
|
|
||||||
:copyright: This stylesheet has been placed in the public domain.
|
|
||||||
|
|
||||||
Default cascading style sheet for the HTML output of Docutils.
|
|
||||||
*/
|
|
||||||
|
|
||||||
.first {
|
|
||||||
margin-top: 0 }
|
|
||||||
|
|
||||||
.last {
|
|
||||||
margin-bottom: 0 }
|
|
||||||
|
|
||||||
a.toc-backref {
|
|
||||||
text-decoration: none ;
|
|
||||||
color: black }
|
|
||||||
|
|
||||||
dd {
|
|
||||||
margin-bottom: 0.5em }
|
|
||||||
|
|
||||||
div.abstract {
|
|
||||||
margin: 2em 5em }
|
|
||||||
|
|
||||||
div.abstract p.topic-title {
|
|
||||||
font-weight: bold ;
|
|
||||||
text-align: center }
|
|
||||||
|
|
||||||
div.attention, div.caution, div.danger, div.error, div.hint,
|
|
||||||
div.important, div.note, div.tip, div.warning {
|
|
||||||
margin: 2em ;
|
|
||||||
border: medium outset ;
|
|
||||||
padding: 1em }
|
|
||||||
|
|
||||||
div.attention p.admonition-title, div.caution p.admonition-title,
|
|
||||||
div.danger p.admonition-title, div.error p.admonition-title,
|
|
||||||
div.warning p.admonition-title {
|
|
||||||
color: red ;
|
|
||||||
font-weight: bold ;
|
|
||||||
font-family: sans-serif }
|
|
||||||
|
|
||||||
div.hint p.admonition-title, div.important p.admonition-title,
|
|
||||||
div.note p.admonition-title, div.tip p.admonition-title {
|
|
||||||
font-weight: bold ;
|
|
||||||
font-family: sans-serif }
|
|
||||||
|
|
||||||
div.dedication {
|
|
||||||
margin: 2em 5em ;
|
|
||||||
text-align: center ;
|
|
||||||
font-style: italic }
|
|
||||||
|
|
||||||
div.dedication p.topic-title {
|
|
||||||
font-weight: bold ;
|
|
||||||
font-style: normal }
|
|
||||||
|
|
||||||
div.figure {
|
|
||||||
margin-left: 2em }
|
|
||||||
|
|
||||||
div.footer, div.header {
|
|
||||||
font-size: smaller }
|
|
||||||
|
|
||||||
div.system-messages {
|
|
||||||
margin: 5em }
|
|
||||||
|
|
||||||
div.system-messages h1 {
|
|
||||||
color: red }
|
|
||||||
|
|
||||||
div.system-message {
|
|
||||||
border: medium outset ;
|
|
||||||
padding: 1em }
|
|
||||||
|
|
||||||
div.system-message p.system-message-title {
|
|
||||||
color: red ;
|
|
||||||
font-weight: bold }
|
|
||||||
|
|
||||||
div.topic {
|
|
||||||
margin: 2em }
|
|
||||||
|
|
||||||
h1.title {
|
|
||||||
text-align: center }
|
|
||||||
|
|
||||||
h2.subtitle {
|
|
||||||
text-align: center }
|
|
||||||
|
|
||||||
hr {
|
|
||||||
width: 75% }
|
|
||||||
|
|
||||||
ol.simple, ul.simple {
|
|
||||||
margin-bottom: 1em }
|
|
||||||
|
|
||||||
ol.arabic {
|
|
||||||
list-style: decimal }
|
|
||||||
|
|
||||||
ol.loweralpha {
|
|
||||||
list-style: lower-alpha }
|
|
||||||
|
|
||||||
ol.upperalpha {
|
|
||||||
list-style: upper-alpha }
|
|
||||||
|
|
||||||
ol.lowerroman {
|
|
||||||
list-style: lower-roman }
|
|
||||||
|
|
||||||
ol.upperroman {
|
|
||||||
list-style: upper-roman }
|
|
||||||
|
|
||||||
p.caption {
|
|
||||||
font-style: italic }
|
|
||||||
|
|
||||||
p.credits {
|
|
||||||
font-style: italic ;
|
|
||||||
font-size: smaller }
|
|
||||||
|
|
||||||
p.label {
|
|
||||||
white-space: nowrap }
|
|
||||||
|
|
||||||
p.topic-title {
|
|
||||||
font-weight: bold }
|
|
||||||
|
|
||||||
pre.address {
|
|
||||||
margin-bottom: 0 ;
|
|
||||||
margin-top: 0 ;
|
|
||||||
font-family: serif ;
|
|
||||||
font-size: 100% }
|
|
||||||
|
|
||||||
pre.line-block {
|
|
||||||
font-family: serif ;
|
|
||||||
font-size: 100% }
|
|
||||||
|
|
||||||
pre.literal-block, pre.doctest-block {
|
|
||||||
margin-left: 2em ;
|
|
||||||
margin-right: 2em ;
|
|
||||||
background-color: #eeeeee }
|
|
||||||
|
|
||||||
span.classifier {
|
|
||||||
font-family: sans-serif ;
|
|
||||||
font-style: oblique }
|
|
||||||
|
|
||||||
span.classifier-delimiter {
|
|
||||||
font-family: sans-serif ;
|
|
||||||
font-weight: bold }
|
|
||||||
|
|
||||||
span.interpreted {
|
|
||||||
font-family: sans-serif }
|
|
||||||
|
|
||||||
span.option-argument {
|
|
||||||
font-style: italic }
|
|
||||||
|
|
||||||
span.pre {
|
|
||||||
white-space: pre }
|
|
||||||
|
|
||||||
span.problematic {
|
|
||||||
color: red }
|
|
||||||
|
|
||||||
table {
|
|
||||||
margin-top: 0.5em ;
|
|
||||||
margin-bottom: 0.5em }
|
|
||||||
|
|
||||||
table.citation {
|
|
||||||
border-left: solid thin gray ;
|
|
||||||
padding-left: 0.5ex }
|
|
||||||
|
|
||||||
table.docinfo {
|
|
||||||
margin: 2em 4em }
|
|
||||||
|
|
||||||
table.footnote {
|
|
||||||
border-left: solid thin black ;
|
|
||||||
padding-left: 0.5ex }
|
|
||||||
|
|
||||||
td, th {
|
|
||||||
padding-left: 0.5em ;
|
|
||||||
padding-right: 0.5em ;
|
|
||||||
vertical-align: top }
|
|
||||||
|
|
||||||
th.docinfo-name, th.field-name {
|
|
||||||
font-weight: bold ;
|
|
||||||
text-align: left ;
|
|
||||||
white-space: nowrap }
|
|
||||||
|
|
||||||
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
|
|
||||||
font-size: 100% }
|
|
||||||
|
|
||||||
tt {
|
|
||||||
background-color: #eeeeee }
|
|
||||||
|
|
||||||
ul.auto-toc {
|
|
||||||
list-style-type: none }
|
|
||||||
|
|
||||||
--></style>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="document" id="new-iterator-concepts">
|
<div class="document" id="new-iterator-concepts">
|
||||||
@ -216,7 +25,7 @@ ul.auto-toc {
|
|||||||
<tr><th class="docinfo-name">Organization:</th>
|
<tr><th class="docinfo-name">Organization:</th>
|
||||||
<td><a class="first reference" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference" href="http://www.osl.iu.edu">Open Systems Lab</a>, University of Hanover <a class="last reference" href="http://www.ive.uni-hannover.de">Institute for Transport Railway Operation and Construction</a></td></tr>
|
<td><a class="first reference" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference" href="http://www.osl.iu.edu">Open Systems Lab</a>, University of Hanover <a class="last reference" href="http://www.ive.uni-hannover.de">Institute for Transport Railway Operation and Construction</a></td></tr>
|
||||||
<tr><th class="docinfo-name">Date:</th>
|
<tr><th class="docinfo-name">Date:</th>
|
||||||
<td>2003-07-12</td></tr>
|
<td>2003-07-13</td></tr>
|
||||||
<tr class="field"><th class="docinfo-name">Number:</th><td class="field-body"><strong>This document is a revised version of the official</strong> N1477=03-0060</td>
|
<tr class="field"><th class="docinfo-name">Number:</th><td class="field-body"><strong>This document is a revised version of the official</strong> N1477=03-0060</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr><th class="docinfo-name">Copyright:</th>
|
<tr><th class="docinfo-name">Copyright:</th>
|
||||||
@ -1123,11 +932,5 @@ LocalWords: TraversalTag typename lvalues DWA Hmm JGS -->
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr class="footer"/>
|
|
||||||
<div class="footer">
|
|
||||||
<a class="reference" href="new-iter-concepts.rst">View document source</a>.
|
|
||||||
Generated on: 2003-07-13 21:54 UTC.
|
|
||||||
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
|
|
||||||
</div>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Reference in New Issue
Block a user