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 :Author: David Abrahams, Jeremy Siek, Thomas Witt
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de :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$ :date: $Date$
:Number: N1476=03-0059 :Number: N1476=03-0059
:copyright: Copyright Dave Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved :copyright: Copyright Dave Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
@@ -268,30 +270,41 @@ invariants of the iterator.
``operator[]`` ``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 Writable iterators built with ``iterator_facade`` implement the
semantics required by the proposed resolution to issue `299`_ and semantics required by the preferred resolution to `issue 299`_ and
adopted by proposal `n1477`_: ``p[n] = x`` is equivalent to ``*(p + n) adopted by proposal `n1477`_: the result of ``p[n]`` is a proxy object
= x``. To make that possible regardless of the other details of the containing a copy of ``p+n``, and ``p[n] = x`` is equivalent to ``*(p
iterator's implementation, the return type of ``operator[]`` is a + n) = x``. This approach will work properly for any random-access
proxy object containing a copy of 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 .. _issue 299: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#299
iterator
.. _`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 The ``reference`` type of a readable iterator (and today's input
convertible to the value type, but accessing members through iterator) need not in fact be a reference, so long as it is
``operator->()`` must still be possible. As a result a conformant convertible to the iterator's ``value_type``. When the ``value_type``
``readable iterator`` must return a proxy from ``operator->()``. 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 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_facade`` instantiation to meet the requirements of its
``iterator_category``. ``iterator_category``.
@@ -352,6 +365,8 @@ which were easily implemented using ``iterator_adaptor``:
* ``filter_iterator``, which provides a view of an iterator range in * ``filter_iterator``, which provides a view of an iterator range in
which some elements of the underlying range are skipped. which some elements of the underlying range are skipped.
.. _counting_iterator:
* ``counting_iterator``, which adapts any incrementable type * ``counting_iterator``, which adapts any incrementable type
(e.g. integers, iterators) so that incrementing/decrementing the (e.g. integers, iterators) so that incrementing/decrementing the
adapted iterator and dereferencing it produces successive values of adapted iterator and dereferencing it produces successive values of
@@ -472,8 +487,8 @@ Class template ``iterator_facade``
typedef Category iterator_category; typedef Category iterator_category;
reference operator*() const; reference operator*() const;
/* see details */ operator->() const; /* see below */ operator->() const;
/* see details */ operator[](difference_type n) const; /* unspecified */ operator[](difference_type n) const;
Derived& operator++(); Derived& operator++();
Derived operator++(int); Derived operator++(int);
Derived& operator--(); Derived& operator--();
@@ -606,49 +621,36 @@ through member functions of class ``iterator_core_access``.
:Returns: ``static_cast<Derived const*>(this)->dereference()`` :Returns: ``static_cast<Derived const*>(this)->dereference()``
*see details* ``operator->() const;`` *see below* ``operator->() const;``
:Requires: :Requires:
:Effects: :Effects:
:Postconditions: :Postconditions:
:Returns: If ``iterator_category`` is a derived class of :Returns: If ``X::reference`` is a reference type, returns an object
``readable_lvalue_iterator_tag`` then the return type is ``pointer`` of type ``X::pointer`` equal to::
and the value returned is
::
&static_cast<Derived const*>(this)->dereference() &static_cast<Derived const*>(this)->dereference()
Otherwise a proxy object is returned. The type of Otherwise returns an object of unspecified type such that, given an
the proxy is implementation defined. The proxy class must have object ``a`` of type ``X``, ``a->m`` is equivalent to ``(w = *a,
the following member function. *w*.m)`` for some temporary object ``w`` of type ``X::value_type``.
::
const value_type* operator->() const;
:Throws: :Throws:
:Complexity: :Complexity:
*see details* ``operator[](difference_type n) const;`` *unspecified* ``operator[](difference_type n) const;``
:Requires: :Requires:
:Effects: :Effects:
:Postconditions: :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 :Returns: an object convertible to ``X::reference`` and holding a copy
value returned is *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``.
static_cast<Derived const*>(this)->dereference()
:Throws: :Throws:
:Complexity: :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 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
matches the resolution of `issue 299`_: ``operator[]`` is only matches the preferred resolution of `issue 299`_: ``operator[]`` is
required to return something convertible to the ``value_type`` (for a only required to return something convertible to the ``value_type``
Readable Iterator), and is required to support assignment ``i[n] = t`` (for a Readable Iterator), and is required to support assignment
(for a Writable Iterator). ``i[n] = t`` (for a Writable Iterator).
=============== ===============