Many edits

[SVN r1226]
This commit is contained in:
Dave Abrahams
2003-04-27 19:31:56 +00:00
parent a83891fb94
commit c72ce2ae74
2 changed files with 48 additions and 46 deletions

View File

@@ -4,7 +4,9 @@
: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`_
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, University of Hanover `Institute for Transport
Railway Operation and Construction`_
:date: $Date$
:Number: N1476=03-0059
:copyright: Copyright Dave Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
@@ -268,30 +270,41 @@ invariants of the iterator.
``operator[]``
================
The indexing operator for a generalized iterator presents special challenges;
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 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
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.
result of indexing the iterator is assignable
iterator
.. _`299`: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#299
.. _issue 299: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#299
``operator->``
==============
For ``readable iterators`` the reference type is only required to be
convertible to the value type, but accessing members through
``operator->()`` must still be possible. As a result a conformant
``readable iterator`` must return a proxy from ``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
``operator->`` and ``operator[]``. Instead it requires each
``iterator_facade`` instantiation to meet the requirements of its
``iterator_category``.
@@ -352,6 +365,8 @@ which were easily implemented using ``iterator_adaptor``:
* ``filter_iterator``, which provides a view of an iterator range in
which some elements of the underlying range are skipped.
.. _counting_iterator:
* ``counting_iterator``, which adapts any incrementable type
(e.g. integers, iterators) so that incrementing/decrementing the
adapted iterator and dereferencing it produces successive values of
@@ -472,8 +487,8 @@ Class template ``iterator_facade``
typedef Category iterator_category;
reference operator*() const;
/* see details */ operator->() const;
/* see details */ operator[](difference_type n) const;
/* see below */ operator->() const;
/* unspecified */ operator[](difference_type n) const;
Derived& operator++();
Derived operator++(int);
Derived& operator--();
@@ -606,49 +621,36 @@ through member functions of class ``iterator_core_access``.
:Returns: ``static_cast<Derived const*>(this)->dereference()``
*see details* ``operator->() const;``
*see below* ``operator->() const;``
:Requires:
:Effects:
:Postconditions:
:Returns: If ``iterator_category`` is a derived class of
``readable_lvalue_iterator_tag`` then the return type is ``pointer``
and the value returned is
::
:Returns: If ``X::reference`` is a reference type, returns an object
of type ``X::pointer`` equal to::
&static_cast<Derived const*>(this)->dereference()
Otherwise a proxy object is returned. The type of
the proxy is implementation defined. The proxy class must have
the following member function.
::
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``.
const value_type* operator->() const;
:Throws:
:Complexity:
*see details* ``operator[](difference_type n) const;``
*unspecified* ``operator[](difference_type n) const;``
:Requires:
:Effects:
:Postconditions:
:Returns: If ``iterator_category`` is a derived class of
``writable_iterator_tag`` then the return type is
a proxy object of implementation defined type ``P``
with the following member functions.
::
operator reference();
P& operator=(value_type const&);
Otherwise the return type is ``value_type`` and the
value returned is
::
static_cast<Derived const*>(this)->dereference()
: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``.
:Throws:
:Complexity:

View File

@@ -262,10 +262,10 @@ of ``reference``; the same as ``operator*``. However, going in this
direction would mean that an iterator satisfying the old Random Access
Iterator requirements would not necessarily be a model of Readable or
Writable Lvalue Iterator. Instead we have chosen a design that
matches the resolution of `issue 299`_: ``operator[]`` is only
required to return something convertible to the ``value_type`` (for a
Readable Iterator), and is required to support assignment ``i[n] = t``
(for a Writable Iterator).
matches the preferred resolution of `issue 299`_: ``operator[]`` is
only required to return something convertible to the ``value_type``
(for a Readable Iterator), and is required to support assignment
``i[n] = t`` (for a Writable Iterator).
===============