more edits

[SVN r1213]
This commit is contained in:
Dave Abrahams
2003-04-27 00:20:50 +00:00
parent 73030b3ac8
commit af92b555d3
2 changed files with 54 additions and 35 deletions

View File

@@ -266,17 +266,25 @@ It is important to note that ``iterator_core_access`` does not open a
safety loophole, as every core member function preserves the safety loophole, as every core member function preserves the
invariants of the iterator. invariants of the iterator.
operator[]() ``operator[]``
============ ================
For operator[]() ``iterator_facade`` implements the semantics required The indexing operator for a generalized iterator presents special challenges;
in the proposed resolution to issue `299`_ and adopted by proposal `n1477`_.
I.e. operator[]() is not required to return an lvalue. Writable iterators built with ``iterator_facade`` implement the
semantics required by the proposed resolution to issue `299`_ and
adopted by proposal `n1477`_: ``p[n] = x`` is equivalent to ``*(p + n)
= x``. To make that possible regardless of the other details of the
iterator's implementation, the return type of ``operator[]`` is a
proxy object containing a copy of
result of indexing the iterator is assignable
iterator
.. _`299`: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#299 .. _`299`: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#299
operator->() ``operator->``
============ ==============
For ``readable iterators`` the reference type is only required to be For ``readable iterators`` the reference type is only required to be
convertible to the value type, but accessing members through convertible to the value type, but accessing members through

View File

@@ -71,39 +71,49 @@ nonintuitive that at least one implementation erroneously assigns
not return true references: there is the often cited example of not return true references: there is the often cited example of
disk-based collections. disk-based collections.
.. I wonder if the disk-based collection argument is valid? I would
tend to do that with an internally stored lvalue. -DWA
.. _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 hard-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_). This iterator 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
iterator) or 2) return the ``value_type`` or a proxy from iterator) or 2) return the ``value_type`` or a proxy from
``operator[]``. Option 1) runs into the problems discussed in `issue ``operator[]``. Option 1) runs into the problems discussed in `issue
198`_, the reference will not be valid after the iterator is 198`_: the reference will not be valid after the iterator is
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 .. 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 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 what you're saying here. I'd fix it myself, but I'm not sure what
you're getting at. -DWA you're getting at. -DWA
.. On second thought, I think the whole paragraph is bogus (sorry).
The conclusion for option 2, "but then we have a counting iterator
that cannot be a random access iterator" is wrong, too: returning a
value from operator[] is compatible with the random access iterator
requirements. I commented it out. -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
Yet another example is a transform iterator, an iterator adaptor that Another difficult-to-categorize iterator is the transform iterator, an
applies a unary function object to the dereference value of the adaptor which applies a unary function object to the dereferenced
wrapped iterator (see `transform_iterator`_). For unary functions value of the some underlying iterator (see `transform_iterator`_).
such as ``times`` the return type of ``operator*`` clearly needs For unary functions such as ``times``, the return type of
to be the ``result_type`` of the function object, which is typically ``operator*`` clearly needs to be the ``result_type`` of the function
not a reference. However, with the current iterator requirements, if object, which is typically not a reference. Because random access
you wrap ``int*`` with a transform iterator, you do not get a random iterators are prequired to return lvalues from ``operator*``, if you
access iterator as expected, but an input iterator. wrap ``int*`` with a transform iterator, you do not get a random
access iterator as might be expected, but an input iterator.
.. _`transform_iterator`: http://www.boost.org/libs/utility/transform_iterator.htm .. _`transform_iterator`: http://www.boost.org/libs/utility/transform_iterator.htm
A fourth example is found in the vertex and edge iterators of the A third example is found in the vertex and edge iterators of the
`Boost Graph Library`_. These iterators return vertex and edge `Boost Graph Library`_. These iterators return vertex and edge
descriptors, which are lightweight handles created on-the-fly. They descriptors, which are lightweight handles created on-the-fly. They
must be returned by-value. As a result, their current standard must be returned by-value. As a result, their current standard
@@ -121,10 +131,11 @@ In short, there are many useful iterators that do not fit into the
current standard iterator categories. As a result, the following bad current standard iterator categories. As a result, the following bad
things happen: things happen:
- Iterators are often miss-categorized. - Iterators are often mis-categorized.
- Algorithm requirements are more strict than necessary, because they can
not separate out the need for random-access from the need for a true reference - Algorithm requirements are more strict than necessary, because they
return type. cannot separate the need for random access or bidirectional
traversal from the need for a true reference return type.
======================== ========================
@@ -276,11 +287,11 @@ direct approach for specifying ``operator[]`` would have a return type
of ``reference``; the same as ``operator*``. However, going in this 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 matches Writable Lvalue Iterator. Instead we have chosen a design that
the resolution of `issue 299`_. So ``operator[]`` is only required to matches the resolution of `issue 299`_: ``operator[]`` is only
return something convertible to the ``value_type`` (for a Readable required to return something convertible to the ``value_type`` (for a
Iterator), and is required to support assignment ``i[n] = t`` (for a Readable Iterator), and is required to support assignment ``i[n] = t``
Writable Iterator). (for a Writable Iterator).
=============== ===============