edits and commentary

[SVN r1184]
This commit is contained in:
Dave Abrahams
2003-04-25 15:17:59 +00:00
parent 4bc2915135
commit 3c78ef32c3

View File

@@ -30,10 +30,13 @@
The standard iterator categories and requirements are flawed because The standard iterator categories and requirements are flawed because
they use a single hierarchy of concepts to address two orthogonal they use a single hierarchy of concepts to address two orthogonal
issues: *iterator traversal* and *value access*. As a result issues: *iterator traversal* and *value access*. As a result, many
algorithms with type requirements expressed by the iterator algorithms with requirements expressed in terms of the iterator
requirements are too strict. Also many concrete iterators can not be categories are too strict. Also, many real-world iterators can not be
accurately categorized. The current iterator concept hierarchy is accurately categorized. A proxy-based iterator with random-access
traversal, for example, may only legally have a category of "input
iterator", so generic algorithms are unable to take advantage of its
random-access capabilities. The current iterator concept hierarchy is
geared towards iterator traversal (hence the category names), while geared towards iterator traversal (hence the category names), while
requirements that address value access sneak in at various places. The requirements that address value access sneak in at various places. The
following table gives a summary of the current value access following table gives a summary of the current value access
@@ -70,8 +73,8 @@ disk-based collections.
.. _issue 96: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#96 .. _issue 96: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#96
Another example of a difficult to categorize iterator is a counting Another example of a hard-to-categorize iterator is a counting
iterator, an iterator the returns a sequence of integers when iterator: an iterator the returns a sequence of integers when
incremented and dereferenced (see counting_iterator_). There are two incremented and dereferenced (see counting_iterator_). There are two
ways to implement this iterator, 1) return a true reference from ways to implement this iterator, 1) return a true reference from
``operator[]`` (a reference to an integer data member of the counting ``operator[]`` (a reference to an integer data member of the counting
@@ -81,6 +84,11 @@ iterator) or 2) return the ``value_type`` or a proxy from
destroyed. Option 2) is therefore a better choice, but then we have a destroyed. Option 2) is therefore a better choice, but then we have a
counting iterator that cannot be a random access iterator. counting iterator that cannot be a random access iterator.
.. Jeremy, option 1 is NOT an option, since there's no way to return a
live reference from operator[]. I think you need to clarify/rework
what you're saying here. I'd fix it myself, but I'm not sure what
you're getting at. -DWA
.. _counting_iterator: http://www.boost.org/libs/utility/counting_iterator.htm .. _counting_iterator: http://www.boost.org/libs/utility/counting_iterator.htm
.. _issue 198: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#198 .. _issue 198: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#198
@@ -123,13 +131,17 @@ things happen:
Impact on the Standard Impact on the Standard
======================== ========================
The new iterator concepts are backwards compatible with the old The new iterator concepts are backward-compatible with the old
iterator requirements, and old iterators are forward compatible with iterator requirements, and old iterators are forward-compatible with
the new iterator concepts. That is to say, iterators that satisfy the the new iterator concepts. That is to say, iterators that satisfy the
old requirements also satisfy appropriate concepts in the new system, old requirements also satisfy appropriate concepts in the new system,
and iterators modeling the new concepts will automatically satisfy the and iterators modeling the new concepts will automatically satisfy the
appropriate old requirements. appropriate old requirements.
.. I think we need to say something about the resolution to allow
convertibility to any of the old-style tags as a TR issue (hope it
made it). -DWA
The algorithms in the standard library benefit from the new iterator The algorithms in the standard library benefit from the new iterator
concepts because the new concepts provide a more accurate way to concepts because the new concepts provide a more accurate way to
express their type requirements. The result is algorithms that are express their type requirements. The result is algorithms that are
@@ -230,7 +242,7 @@ combined into a single type using the following `iterator_tag` class.
:: ::
template <class AccessTag, class TraversalTag> template <class AccessTag, class TraversalTag>
struct iterator_tag : /* appropriate old category */ struct iterator_tag : /* appropriate old category or categories */
{ {
typedef AccessTag access; typedef AccessTag access;
typedef TraversalTag traversal; typedef TraversalTag traversal;
@@ -530,7 +542,7 @@ Addition to [lib.iterator.synopsis]
template <class Iterator> struct traversal_category; template <class Iterator> struct traversal_category;
template <class AccessTag, class TraversalTag> template <class AccessTag, class TraversalTag>
struct iterator_tag : /* appropriate old category */ { struct iterator_tag : /* appropriate old category or categories */ {
typedef AccessTag access; typedef AccessTag access;
typedef TraversalTag traversal; typedef TraversalTag traversal;
}; };
@@ -556,7 +568,6 @@ Addition to [lib.iterator.synopsis]
struct null_category_tag { }; struct null_category_tag { };
struct input_output_iterator_tag : input_iterator_tag, output_iterator_tag {}; struct input_output_iterator_tag : input_iterator_tag, output_iterator_tag {};
Addition to [lib.iterator.traits] Addition to [lib.iterator.traits]
================================= =================================
@@ -569,28 +580,38 @@ pseudo-code.
:: ::
inherit-category(access-tag, traversal-tag) = inherit-category(access-tag, traversal-tag) =
if (access-tag is convertible to readable_lvalue_iterator_tag (access-tag is convertible to readable_lvalue_iterator_tag
or access-tag is convertible to writable_lvalue_iterator_tag) { or access-tag is convertible to writable_lvalue_iterator_tag
if (traversal-tag is convertible to random_access_traversal_tag) )
return random_access_iterator_tag; ? (
else if (traversal-tag is convertible to bidirectional_traversal_tag) (traversal-tag is convertible to random_access_traversal_tag)
return bidirectional_iterator_tag; ? random_access_iterator_tag
else if (traversal-tag is convertible to forward_traversal_tag)
return forward_iterator_tag;
else
return null_category_tag;
} else if (access-tag is convertible to readable_writable_iterator_tag
and traversal-tag is convertible to single_pass_iterator_tag)
return input_output_iterator_tag;
else if (access-tag is convertible to readable_iterator_tag
and traversal-tag is convertible to single_pass_iterator_tag)
return input_iterator_tag;
else if (access-tag is convertible to writable_iterator_tag
and traversal-tag is convertible to incrementable_iterator_tag)
return output_iterator_tag;
else
return null_category_tag;
: (traversal-tag is convertible to bidirectional_traversal_tag)
? bidirectional_iterator_tag
: (traversal-tag is convertible to forward_traversal_tag)
? forward_iterator_tag
: null_category_tag
)
: (access-tag is convertible to readable_writable_iterator_tag
and traversal-tag is convertible to single_pass_iterator_tag)
? input_output_iterator_tag
: (access-tag is convertible to readable_iterator_tag
and traversal-tag is convertible to single_pass_iterator_tag)
? input_iterator_tag
: (access-tag is convertible to writable_iterator_tag
and traversal-tag is convertible to incrementable_iterator_tag)
? output_iterator_tag
: null_category_tag;
.. Jeremy, I'm not attached to the rewrite above; I just did it to see
if I could make it clearer please feel free to rewrite if you don't
like it.
The ``access_category`` and ``traversal_category`` class templates are The ``access_category`` and ``traversal_category`` class templates are
traits classes. For iterators whose traits classes. For iterators whose