forked from boostorg/iterator
removed iterator_tag and reworded some paragraphs
[SVN r21046]
This commit is contained in:
@ -299,74 +299,21 @@ given in the following diagram.
|
|||||||
Like the old iterator requirements, we provide tags for purposes of
|
Like the old iterator requirements, we provide tags for purposes of
|
||||||
dispatching based on the traversal concepts. The tags are related via
|
dispatching based on the traversal concepts. The tags are related via
|
||||||
inheritance so that a tag is convertible to another tag if the concept
|
inheritance so that a tag is convertible to another tag if the concept
|
||||||
associated with the first tag is a refinement of the second tag.
|
associated with the first tag is a refinement of the second tag. Our
|
||||||
Since the access concepts are not related via refinement, but instead
|
design reuses ``iterator_traits<Iter>::iterator_category`` as the
|
||||||
cover orthogonal issues, we do not use tags for the access concepts,
|
access mechanism for the traversal tag. If an iterator wishes to meet
|
||||||
but instead use the equivalent of a bit field.
|
the requirements of both a new iterator concept and an old iterator
|
||||||
|
concept, it can use an iterator category type that inherits from both
|
||||||
|
the the old iterator tag and the new traversal tag.
|
||||||
|
|
||||||
We provide an access mechanism for mapping iterator types to the new
|
We do not provide tags for the purposes of dispatching based on the
|
||||||
traversal tags and access bit field. Our design reuses
|
access concepts. There are two reasons: we could not find a way to
|
||||||
``iterator_traits<Iter>::iterator_category`` as the access
|
automatically infer the right access tags for old-style iterators and
|
||||||
mechanism. To that end, the access and traversal information is
|
the need for dispatching based on the access concepts is not as great.
|
||||||
bundled into a single type using the following `iterator_tag` class.
|
|
||||||
|
|
||||||
::
|
A difficult design decision concerned the ``operator[]``. The direct
|
||||||
|
approach for specifying ``operator[]`` would have a return type of
|
||||||
enum iterator_access { readable_iterator = 1, writable_iterator = 2,
|
``reference``; the same as ``operator*``. However, going in this
|
||||||
swappable_iterator = 4, lvalue_iterator = 8 };
|
|
||||||
|
|
||||||
template <unsigned int access_bits, class TraversalTag>
|
|
||||||
struct iterator_tag : /* appropriate old category or categories */ {
|
|
||||||
static const iterator_access access =
|
|
||||||
(iterator_access)access_bits &
|
|
||||||
(readable_iterator | writable_iterator | swappable_iterator);
|
|
||||||
typedef TraversalTag traversal;
|
|
||||||
};
|
|
||||||
|
|
||||||
The ``access_bits`` argument is declared to be ``unsigned int``
|
|
||||||
instead of the enum ``iterator_access`` for convenience of use. For
|
|
||||||
example, the expression ``(readable_iterator | writable_iterator)``
|
|
||||||
produces an unsigned int, not an ``iterator_access``. The purpose of
|
|
||||||
the ``lvalue_iterator`` part of the ``iterator_access`` enum is to
|
|
||||||
communicate to ``iterator_tag`` whether the reference type is an
|
|
||||||
lvalue so that the appropriate old category can be chosen for the base
|
|
||||||
class. The ``lvalue_iterator`` bit is not recorded in the
|
|
||||||
``iterator_tag::access`` data member.
|
|
||||||
|
|
||||||
The ``iterator_tag`` class template is derived from the appropriate
|
|
||||||
iterator tag or tags from the old requirements based on the access
|
|
||||||
bits and traversal tag passed as template parameters. The algorithm
|
|
||||||
for determining the old tag or tags picks the least-refined old
|
|
||||||
concepts that include all of the requirements of the access and
|
|
||||||
traversal concepts (that is, the closest fit), if any such category
|
|
||||||
exists. For example, the category tag for a Readable Single Pass
|
|
||||||
Iterator will always be derived from ``input_iterator_tag``, while the
|
|
||||||
category tag for a Single Pass Iterator that is both Readable and
|
|
||||||
Writable will be derived from both ``input_iterator_tag`` and
|
|
||||||
``output_iterator_tag``.
|
|
||||||
|
|
||||||
We also provide several helper classes that make it convenient to
|
|
||||||
obtain the access and traversal characteristics of an iterator. These
|
|
||||||
helper classes work both for iterators whose ``iterator_category`` is
|
|
||||||
``iterator_tag`` and also for iterators using the original iterator
|
|
||||||
categories.
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
template <class Iterator> struct is_readable { typedef ... type; };
|
|
||||||
template <class Iterator> struct is_writable { typedef ... type; };
|
|
||||||
template <class Iterator> struct is_swappable { typedef ... type; };
|
|
||||||
template <class Iterator> struct traversal_category { typedef ... type; };
|
|
||||||
|
|
||||||
|
|
||||||
We do not include a helper class ``is_lvalue_iterator`` because that
|
|
||||||
can easily be deduced by checking whether
|
|
||||||
``iterator_traits<Iterator>::reference`` is a real reference.
|
|
||||||
|
|
||||||
|
|
||||||
The most difficult design decision concerned the ``operator[]``. The
|
|
||||||
direct approach for specifying ``operator[]`` would have a return type
|
|
||||||
of ``reference``; the same as ``operator*``. However, going in this
|
|
||||||
direction would mean that an iterator satisfying the old Random Access
|
direction would mean that an iterator satisfying the old Random Access
|
||||||
Iterator requirements would not necessarily be a model of Readable or
|
Iterator requirements would not necessarily be a model of Readable or
|
||||||
Writable Lvalue Iterator. Instead we have chosen a design that
|
Writable Lvalue Iterator. Instead we have chosen a design that
|
||||||
|
Reference in New Issue
Block a user