kill redundancy; final edits

[SVN r1250]
This commit is contained in:
Dave Abrahams
2003-04-28 15:02:42 +00:00
parent e2b3a260d5
commit a529a82a66
2 changed files with 98 additions and 92 deletions

View File

@@ -232,8 +232,10 @@ In addition to implementing the core interface functions, an iterator
derived from ``iterator_facade`` typically defines several derived from ``iterator_facade`` typically defines several
constructors. To model any of the standard iterator concepts, the constructors. To model any of the standard iterator concepts, the
iterator must at least have a copy constructor. Also, if the iterator iterator must at least have a copy constructor. Also, if the iterator
is meant to be interoperable (between for example, constant and type ``X`` is meant to be automatically interoperate with another
mutable versions of the iterator) then there must be a conversion iterator type ``Y`` (as with constant and mutable iterators) then
there must be an implicit conversion from ``X`` to ``Y`` or from ``Y``
to ``X`` (but not both), typically implemented as a conversion
constructor. Also, if the iterator is to model Forward Traversal constructor. Also, if the iterator is to model Forward Traversal
Iterator, a default constructor is required. Iterator, a default constructor is required.
@@ -268,14 +270,16 @@ derived class only needs to grant friendship to
``iterator_core_access`` to make his core member functions available ``iterator_core_access`` to make his core member functions available
to the library. to the library.
.. This is no long uptodate -thw .. This is no long uptodate -thw
``iterator_core_access`` will be typically implemented as an empty .. Yes it is; I made sure of it! -DWA
class containing only private static member functions which invoke the
iterator core member functions. There is, however, no need to ``iterator_core_access`` will be typically implemented as an empty
standardize the gateway protocol. Note that even if class containing only private static member functions which invoke the
``iterator_core_access`` used public member functions it would not iterator core member functions. There is, however, no need to
open a safety loophole, as every core member function preserves the standardize the gateway protocol. Note that even if
invariants of the iterator. ``iterator_core_access`` used public member functions it would not
open a safety loophole, as every core member function preserves the
invariants of the iterator.
``operator[]`` ``operator[]``
================ ================
@@ -334,22 +338,24 @@ instance of the ``Base`` type, which it stores as a member.
the underlying iterator object of a ``reverse_iterator`` adaptor. the underlying iterator object of a ``reverse_iterator`` adaptor.
The user of ``iterator_adaptor`` creates a class derived from an The user of ``iterator_adaptor`` creates a class derived from an
instantiation of ``iterator_adaptor`` and then selectively overrides instantiation of ``iterator_adaptor`` and then selectively
some of the core operations by implementing the (non-virtual) member redefines some of the core member functions described in the table
functions described in the table above. The ``Base`` type above. The ``Base`` type need not meet the full requirements for an
need not meet the full requirements for an iterator. It need iterator. It need only support the operations used by the core
only support the operations that are not overridden by the interface functions of ``iterator_adaptor`` that have not been
users derived class. redefined in the user's derived class.
Several of the template parameters of ``iterator_adaptor`` have
``use_default`` as their default. The reason for this is twofold.
First, it allows the user to make use of a default parameter even when
the user wants to specify a parameter later in the parameter list.
Second, the defaults are fairly complicated, so metafunctions are
required, and ``use_default`` is a way to hide the metafunctions.
.. Dave, is the above accurate? -JGS
Several of the template parameters of ``iterator_adaptor`` default to
``use_default``. This allows the user to make use of a default
parameter even when the user wants to specify a parameter later in the
parameter list. Also, the defaults for the corresponding associated
types are fairly complicated, so metaprogramming is required to
compute them, and ``use_default`` can help to simplify the
implementation. Finally, ``use_default`` is not left unspecified
because specification helps to highlight that the ``Reference``
template parameter may not always be identical to the iterator's
``reference`` type, and will keep users making mistakes based on that
assumtion.
Specialized Adaptors Specialized Adaptors
==================== ====================
@@ -579,10 +585,9 @@ out of the overload set when the types are not interoperable.]
The ``Derived`` template parameter must be a class derived from The ``Derived`` template parameter must be a class derived from
``iterator_facade``. ``iterator_facade``.
The default for the ``Reference`` parameter is a non-const reference The default for the ``Reference`` parameter is `Value&`` if the access
to ``Value`` if the access category for ``iterator_facade`` derives category for ``iterator_facade`` is implicitly convertible to
from ``writable_iterator_tag``, and a const reference to ``Value`` ``writable_iterator_tag``, and ``const Value&`` otherwise.
otherwise.
The following table describes the other requirements on the The following table describes the other requirements on the
``Derived`` parameter. Depending on the resulting iterator's ``Derived`` parameter. Depending on the resulting iterator's
@@ -650,9 +655,9 @@ through member functions of class ``iterator_core_access``.
object ``a`` of type ``X``, ``a->m`` is equivalent to ``(w = *a, object ``a`` of type ``X``, ``a->m`` is equivalent to ``(w = *a,
w.m)`` for some temporary object ``w`` of type ``X::value_type``. w.m)`` for some temporary object ``w`` of type ``X::value_type``.
The type ``X::pointer`` is a non-const pointer to ``Value`` The type ``X::pointer`` is ``Value*`` if the access category for
if the access category for ``X`` derives from ``writable_iterator_tag``, ``X`` is implicitly convertible to ``writable_iterator_tag``, and
and a const pointer to ``Value`` otherwise. ``Value const*`` otherwise.
*unspecified* ``operator[](difference_type n) const;`` *unspecified* ``operator[](difference_type n) const;``
@@ -749,12 +754,12 @@ The ``iterator_adaptor`` is a base class template derived from an
instantiation of ``iterator_facade``. The core interface functions instantiation of ``iterator_facade``. The core interface functions
expected by ``iterator_facade`` are implemented in terms of the expected by ``iterator_facade`` are implemented in terms of the
``iterator_adaptor``\ 's ``Base`` template parameter. A class derived ``iterator_adaptor``\ 's ``Base`` template parameter. A class derived
from ``iterator_adaptor`` typically implements some of the from ``iterator_adaptor`` typically redefines some of the core
(non-virtual) core interface functions to adapt the behavior of the interface functions to adapt the behavior of the ``Base`` type.
``Base`` type. Whether the derived class models any of the standard Whether the derived class models any of the standard iterator concepts
iterator concepts depends on what operations are supported by the depends on the operations supported by the ``Base`` type and which
``Base`` type and which core interface functions of core interface functions of ``iterator_facade`` are redefined in the
``iterator_facade`` are overridden in the ``Derived`` class. ``Derived`` class.
Class template ``iterator_adaptor`` Class template ``iterator_adaptor``
@@ -811,7 +816,7 @@ Class template ``iterator_adaptor``
The ``Derived`` template parameter must be a derived class of The ``Derived`` template parameter must be a derived class of
``iterator_adaptor``. The ``Base`` type must implement the expressions ``iterator_adaptor``. The ``Base`` type must implement the expressions
involving ``m_iterator`` in the specifications of those private member involving ``m_iterator`` in the specifications of those private member
functions of ``iterator_adaptor`` that are not overridden by the functions of ``iterator_adaptor`` that are not redefined by the
``Derived`` class and that are needed to model the concept ``Derived`` class and that are needed to model the concept
corresponding to the chosen ``Category`` according to the requirements corresponding to the chosen ``Category`` according to the requirements
of ``iterator_facade``. The rest of the template parameters specify of ``iterator_facade``. The rest of the template parameters specify
@@ -822,46 +827,46 @@ following pseudo-code specifies the traits types for
:: ::
if (Value == use_default) if (Value == use_default)
value_type = iterator_traits<Base>::value_type; value_type = iterator_traits<Base>::value_type;
else else
value_type = remove_cv<Value>::type; value_type = remove_cv<Value>::type;
if (Reference == use_default) { if (Reference == use_default) {
if (Value == use_default) if (Value == use_default)
reference = iterator_traits<Base>::reference; reference = iterator_traits<Base>::reference;
else else
reference = Value&; reference = Value&;
} else } else
reference = Reference; reference = Reference;
if (Distance == use_default) if (Distance == use_default)
difference_type = iterator_traits<Base>::difference_type; difference_type = iterator_traits<Base>::difference_type;
else else
difference_type = Distance; difference_type = Distance;
if (Category == use_default) if (Category == use_default)
iterator_category = iterator_tag< iterator_category = iterator_tag<
access_category< access_category<
iterator< iterator_traits<Base>::iterator_category, iterator< iterator_traits<Base>::iterator_category,
Value, Value,
Distance, Distance,
Value*, Value*,
Reference > >, Reference > >,
traversal_category< traversal_category<
iterator< iterator_traits<Base>::iterator_category, iterator< iterator_traits<Base>::iterator_category,
Value, Value,
Distance, Distance,
Value*, Value*,
Reference > > Reference > >
else else
iterator_category = Category; iterator_category = Category;
.. Replaced with new semantics --thw .. Replaced with new semantics --thw
if (Category == use_default) if (Category == use_default)
iterator_category = iterator_traits<Base>::iterator_category; iterator_category = iterator_traits<Base>::iterator_category;
else else
iterator_category = Category; iterator_category = Category;
@@ -946,6 +951,14 @@ Specialized adaptors [lib.iterator.special.adaptors]
formally -DWA formally -DWA
[*Note:* The ``enable_if_convertible<X,Y>::type`` expression used in
this section is for exposition purposes. The converting constructors
for specialized adaptors should be only be in an overload set provided
that an object of type ``X`` is implicitly convertible to an object of
type ``Y``. The ``enable_if_convertible`` approach uses SFINAE to
take the constructor out of the overload set when the types are not
implicitly convertible.]
Indirect iterator Indirect iterator
----------------- -----------------
@@ -984,7 +997,7 @@ Class template ``indirect_iterator``
indirect_iterator< indirect_iterator<
Iterator2, Value2, Category2, Reference2, Difference2 Iterator2, Value2, Category2, Reference2, Difference2
> const& y > const& y
, typename enable_if_convertible<Iterator2, Iterator>::type* = 0 , typename enable_if_convertible<Iterator2, Iterator>::type* = 0 // exposition
); );
private: // as-if specification private: // as-if specification
typename indirect_iterator::reference dereference() const typename indirect_iterator::reference dereference() const
@@ -993,7 +1006,6 @@ Class template ``indirect_iterator``
} }
}; };
``indirect_iterator`` requirements ``indirect_iterator`` requirements
.................................. ..................................
@@ -1049,15 +1061,14 @@ modeled by the value type of ``Iterator``.
> >
indirect_iterator( indirect_iterator(
indirect_iterator< indirect_iterator<
Iterator2, Value2, Category2, Reference2, Difference2 Iterator2, Value2, Category2, Reference2, Difference2
> const& y > const& y
, typename enable_if_convertible<Iterator2, Iterator>::type* = 0 , typename enable_if_convertible<Iterator2, Iterator>::type* = 0 // exposition
); );
:Requires: ``this->base()`` and ``y.base()`` must be mutually convertible. :Requires: ``Iterator2`` is implicitly convertible to ``Iterator``.
:Returns: An instance of ``indirect_iterator`` that is a copy of ``y``. :Returns: An instance of ``indirect_iterator`` that is a copy of ``y``.
Reverse iterator Reverse iterator
---------------- ----------------
@@ -1084,7 +1095,7 @@ Class template ``reverse_iterator``
template<class OtherIterator> template<class OtherIterator>
reverse_iterator( reverse_iterator(
reverse_iterator<OtherIterator> const& r reverse_iterator<OtherIterator> const& r
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
); );
private: // as-if specification private: // as-if specification
@@ -1095,14 +1106,14 @@ Class template ``reverse_iterator``
void advance(typename reverse_iterator::difference_type n) void advance(typename reverse_iterator::difference_type n)
{ {
this->base_reference() += -n; this->base_reference() += -n;
} }
template <class OtherIterator> template <class OtherIterator>
typename reverse_iterator::difference_type typename reverse_iterator::difference_type
distance_to(reverse_iterator<OtherIterator> const& y) const distance_to(reverse_iterator<OtherIterator> const& y) const
{ {
return this->base_reference() - y.base(); return this->base_reference() - y.base();
} }
}; };
@@ -1134,10 +1145,10 @@ by ``Iterator``.
template<class OtherIterator> template<class OtherIterator>
reverse_iterator( reverse_iterator(
reverse_iterator<OtherIterator> const& r reverse_iterator<OtherIterator> const& r
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
); );
:Requires: ``this->base()`` and ``r.base()`` must be mutually convertible. :Requires: ``OtherIterator`` is implicitly convertible to ``Iterator``.
:Returns: An instance of ``reverse_iterator`` that is a copy of ``r``. :Returns: An instance of ``reverse_iterator`` that is a copy of ``r``.
@@ -1171,7 +1182,7 @@ Class template ``transform_iterator``
template<class OtherIterator, class R2, class V2> template<class OtherIterator, class R2, class V2>
transform_iterator( transform_iterator(
transform_iterator<AdaptableUnaryFunction, OtherIterator, R2, V2> const& t transform_iterator<AdaptableUnaryFunction, OtherIterator, R2, V2> const& t
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
); );
AdaptableUnaryFunction functor() const; AdaptableUnaryFunction functor() const;
@@ -1232,11 +1243,11 @@ The ``value_type`` of ``transform_iterator`` is
template<class OtherIterator, class R2, class V2> template<class OtherIterator, class R2, class V2>
transform_iterator( transform_iterator(
transform_iterator<AdaptableUnaryFunction, OtherIterator, R2, V2> const& t transform_iterator<AdaptableUnaryFunction, OtherIterator, R2, V2> const& t
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
); );
:Returns: An instance of ``transform_iterator`` that is a copy of ``t``. :Returns: An instance of ``transform_iterator`` that is a copy of ``t``.
:Requires: ``OtherIterator`` is implicitly convertible to ``Iterator``.
``AdaptableUnaryFunction functor() const;`` ``AdaptableUnaryFunction functor() const;``
@@ -1361,11 +1372,11 @@ expression ``p(x)`` must be valid where ``p`` is an object of type
template <class OtherIterator> template <class OtherIterator>
filter_iterator( filter_iterator(
filter_iterator<Predicate, OtherIterator> const& t filter_iterator<Predicate, OtherIterator> const& t
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
);`` );``
:Requires: ``*this`` and ``t`` must be mutually convertible. :Requires: ``OtherIterator`` is implicitly convertible to ``Iterator``.
:Returns: A copy of iterator ``t``. :Returns: A copy of iterator ``t``.
@@ -1412,15 +1423,14 @@ Class template ``counting_iterator``
private: private:
typename counting_iterator::reference dereference() const typename counting_iterator::reference dereference() const
{ {
return this->base_reference(); return this->base_reference();
} }
}; };
[*Note:* implementers are encouraged to provide a [*Note:* implementers are encouraged to provide an implementation of
override of ``distance_to`` that avoids overflows ``distance_to`` and a ``difference_type`` that avoids overflows in
in the cases when the ``Incrementable`` type the cases when the ``Incrementable`` type is a numeric type.]
is a numeric type.]
``counting_iterator`` requirements ``counting_iterator`` requirements
---------------------------------- ----------------------------------

View File

@@ -92,11 +92,7 @@ namespace boost
, typename const_qualified<Value, AccessCategory>::type* , typename const_qualified<Value, AccessCategory>::type*
, typename mpl::if_< , Reference
is_same<Reference, use_default>
, typename const_qualified<Value, AccessCategory>::type&
, Reference
>::type
> >
type; type;
}; };