From a529a82a667c638b8ff3d45fb093e548dce42bca Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 28 Apr 2003 15:02:42 +0000 Subject: [PATCH] kill redundancy; final edits [SVN r1250] --- doc/facade-and-adaptor.rst | 184 +++++++++++---------- include/boost/iterator/iterator_facade.hpp | 6 +- 2 files changed, 98 insertions(+), 92 deletions(-) diff --git a/doc/facade-and-adaptor.rst b/doc/facade-and-adaptor.rst index e6c2743..bd0df73 100755 --- a/doc/facade-and-adaptor.rst +++ b/doc/facade-and-adaptor.rst @@ -232,8 +232,10 @@ In addition to implementing the core interface functions, an iterator derived from ``iterator_facade`` typically defines several constructors. To model any of the standard iterator concepts, the iterator must at least have a copy constructor. Also, if the iterator -is meant to be interoperable (between for example, constant and -mutable versions of the iterator) then there must be a conversion +type ``X`` is meant to be automatically interoperate with another +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 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 to the library. - .. This is no long uptodate -thw - ``iterator_core_access`` will be typically implemented as an empty - class containing only private static member functions which invoke the - iterator core member functions. There is, however, no need to - standardize the gateway protocol. Note that even if - ``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. +.. This is no long uptodate -thw +.. Yes it is; I made sure of it! -DWA + +``iterator_core_access`` will be typically implemented as an empty +class containing only private static member functions which invoke the +iterator core member functions. There is, however, no need to +standardize the gateway protocol. Note that even if +``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[]`` ================ @@ -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 user of ``iterator_adaptor`` creates a class derived from an -instantiation of ``iterator_adaptor`` and then selectively overrides -some of the core operations by implementing the (non-virtual) member -functions described in the table above. The ``Base`` type -need not meet the full requirements for an iterator. It need -only support the operations that are not overridden by the -users 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 +instantiation of ``iterator_adaptor`` and then selectively +redefines some of the core member functions described in the table +above. The ``Base`` type need not meet the full requirements for an +iterator. It need only support the operations used by the core +interface functions of ``iterator_adaptor`` that have not been +redefined in the user's derived class. +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 ==================== @@ -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 ``iterator_facade``. -The default for the ``Reference`` parameter is a non-const reference -to ``Value`` if the access category for ``iterator_facade`` derives -from ``writable_iterator_tag``, and a const reference to ``Value`` -otherwise. +The default for the ``Reference`` parameter is `Value&`` if the access +category for ``iterator_facade`` is implicitly convertible to +``writable_iterator_tag``, and ``const Value&`` otherwise. The following table describes the other requirements on the ``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, w.m)`` for some temporary object ``w`` of type ``X::value_type``. - The type ``X::pointer`` is a non-const pointer to ``Value`` - if the access category for ``X`` derives from ``writable_iterator_tag``, - and a const pointer to ``Value`` otherwise. + The type ``X::pointer`` is ``Value*`` if the access category for + ``X`` is implicitly convertible to ``writable_iterator_tag``, and + ``Value const*`` otherwise. *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 expected by ``iterator_facade`` are implemented in terms of the ``iterator_adaptor``\ 's ``Base`` template parameter. A class derived -from ``iterator_adaptor`` typically implements some of the -(non-virtual) core interface functions to adapt the behavior of the -``Base`` type. Whether the derived class models any of the standard -iterator concepts depends on what operations are supported by the -``Base`` type and which core interface functions of -``iterator_facade`` are overridden in the ``Derived`` class. +from ``iterator_adaptor`` typically redefines some of the core +interface functions to adapt the behavior of the ``Base`` type. +Whether the derived class models any of the standard iterator concepts +depends on the operations supported by the ``Base`` type and which +core interface functions of ``iterator_facade`` are redefined in the +``Derived`` class. Class template ``iterator_adaptor`` @@ -811,7 +816,7 @@ Class template ``iterator_adaptor`` The ``Derived`` template parameter must be a derived class of ``iterator_adaptor``. The ``Base`` type must implement the expressions 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 corresponding to the chosen ``Category`` according to the requirements 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) - value_type = iterator_traits::value_type; + value_type = iterator_traits::value_type; else - value_type = remove_cv::type; + value_type = remove_cv::type; if (Reference == use_default) { - if (Value == use_default) - reference = iterator_traits::reference; - else - reference = Value&; + if (Value == use_default) + reference = iterator_traits::reference; + else + reference = Value&; } else - reference = Reference; + reference = Reference; if (Distance == use_default) - difference_type = iterator_traits::difference_type; + difference_type = iterator_traits::difference_type; else - difference_type = Distance; + difference_type = Distance; if (Category == use_default) - iterator_category = iterator_tag< - access_category< - iterator< iterator_traits::iterator_category, - Value, - Distance, - Value*, - Reference > >, - traversal_category< - iterator< iterator_traits::iterator_category, - Value, - Distance, - Value*, - Reference > > + iterator_category = iterator_tag< + access_category< + iterator< iterator_traits::iterator_category, + Value, + Distance, + Value*, + Reference > >, + traversal_category< + iterator< iterator_traits::iterator_category, + Value, + Distance, + Value*, + Reference > > else - iterator_category = Category; + iterator_category = Category; .. Replaced with new semantics --thw if (Category == use_default) - iterator_category = iterator_traits::iterator_category; + iterator_category = iterator_traits::iterator_category; else - iterator_category = Category; + iterator_category = Category; @@ -946,6 +951,14 @@ Specialized adaptors [lib.iterator.special.adaptors] formally -DWA +[*Note:* The ``enable_if_convertible::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 ----------------- @@ -984,7 +997,7 @@ Class template ``indirect_iterator`` indirect_iterator< Iterator2, Value2, Category2, Reference2, Difference2 > const& y - , typename enable_if_convertible::type* = 0 + , typename enable_if_convertible::type* = 0 // exposition ); private: // as-if specification typename indirect_iterator::reference dereference() const @@ -993,7 +1006,6 @@ Class template ``indirect_iterator`` } }; - ``indirect_iterator`` requirements .................................. @@ -1049,15 +1061,14 @@ modeled by the value type of ``Iterator``. > indirect_iterator( indirect_iterator< - Iterator2, Value2, Category2, Reference2, Difference2 + Iterator2, Value2, Category2, Reference2, Difference2 > const& y - , typename enable_if_convertible::type* = 0 + , typename enable_if_convertible::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``. - Reverse iterator ---------------- @@ -1084,7 +1095,7 @@ Class template ``reverse_iterator`` template reverse_iterator( reverse_iterator const& r - , typename enable_if_convertible::type* = 0 + , typename enable_if_convertible::type* = 0 // exposition ); private: // as-if specification @@ -1095,14 +1106,14 @@ Class template ``reverse_iterator`` void advance(typename reverse_iterator::difference_type n) { - this->base_reference() += -n; + this->base_reference() += -n; } template typename reverse_iterator::difference_type distance_to(reverse_iterator const& y) const { - return this->base_reference() - y.base(); + return this->base_reference() - y.base(); } }; @@ -1134,10 +1145,10 @@ by ``Iterator``. template reverse_iterator( reverse_iterator const& r - , typename enable_if_convertible::type* = 0 + , typename enable_if_convertible::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``. @@ -1171,7 +1182,7 @@ Class template ``transform_iterator`` template transform_iterator( transform_iterator const& t - , typename enable_if_convertible::type* = 0 + , typename enable_if_convertible::type* = 0 // exposition ); AdaptableUnaryFunction functor() const; @@ -1232,11 +1243,11 @@ The ``value_type`` of ``transform_iterator`` is template transform_iterator( transform_iterator const& t - , typename enable_if_convertible::type* = 0 + , typename enable_if_convertible::type* = 0 // exposition ); :Returns: An instance of ``transform_iterator`` that is a copy of ``t``. - +:Requires: ``OtherIterator`` is implicitly convertible to ``Iterator``. ``AdaptableUnaryFunction functor() const;`` @@ -1361,11 +1372,11 @@ expression ``p(x)`` must be valid where ``p`` is an object of type template filter_iterator( - filter_iterator const& t - , typename enable_if_convertible::type* = 0 // exposition - );`` + filter_iterator const& t + , typename enable_if_convertible::type* = 0 // exposition + );`` -:Requires: ``*this`` and ``t`` must be mutually convertible. +:Requires: ``OtherIterator`` is implicitly convertible to ``Iterator``. :Returns: A copy of iterator ``t``. @@ -1412,15 +1423,14 @@ Class template ``counting_iterator`` private: typename counting_iterator::reference dereference() const { - return this->base_reference(); + return this->base_reference(); } }; -[*Note:* implementers are encouraged to provide a - override of ``distance_to`` that avoids overflows - in the cases when the ``Incrementable`` type - is a numeric type.] +[*Note:* implementers are encouraged to provide an implementation of + ``distance_to`` and a ``difference_type`` that avoids overflows in + the cases when the ``Incrementable`` type is a numeric type.] ``counting_iterator`` requirements ---------------------------------- diff --git a/include/boost/iterator/iterator_facade.hpp b/include/boost/iterator/iterator_facade.hpp index a901d40..86249b9 100644 --- a/include/boost/iterator/iterator_facade.hpp +++ b/include/boost/iterator/iterator_facade.hpp @@ -92,11 +92,7 @@ namespace boost , typename const_qualified::type* - , typename mpl::if_< - is_same - , typename const_qualified::type& - , Reference - >::type + , Reference > type; };