diff --git a/doc/facade-and-adaptor.rst b/doc/facade-and-adaptor.rst index 9dc635e..44a8843 100755 --- a/doc/facade-and-adaptor.rst +++ b/doc/facade-and-adaptor.rst @@ -361,6 +361,16 @@ Standard compliant iterators). Proposed Text =============== + +Two forward traversal iterator types ``X`` and ``Y`` are +*interoperable* if one and only one is convertible to the other and +for any object ``x`` of type ``X`` and ``y`` of type ``Y``, if ``x == +y``, ``y == x``, ``x != y``, ``y != x`` are well-defined. Two random +access traversal iterators are *interoperable* if, in addition, +``<``,``<=``,``>=``,``>``, and - are well-defined. + + + Header ```` synopsis [lib.iterator.helper.synopsis] ======================================================================= @@ -430,39 +440,9 @@ Header ```` synopsis [lib.iterator.helper.synopsis] Iterator facade [lib.iterator.facade] ===================================== - -The iterator requirements define a rich interface, containing many -redundant operators, so that using iterators is convenient. The -``iterator_facade`` class template makes it easier to create iterators -by implementing the rich interface of standard iterators in terms of a -few core functions. The user of ``iterator_facade`` derives his -iterator class from an instantiation of ``iterator_facade`` and -defines member functions implementing the core behaviors. - -.. Jeremy, I think this text is rather inappropriate for the - standard. This is not the place to discuss motivation, for - example. Compare with the standard text for vector: - - 1 A vector is a kind of sequence that supports random access - iterators. In addition, it supports (amortized) constant time - insert and erase operations at the end; insert and erase in the - middle take linear time. Storage management is handled - automatically, though hints can be given to improve efficiency. - - 2 A vector satisfies all of the requirements of a container and - of a reversible container (given in two tables in 23.1) and of a - sequence, including most of the optional sequence requirements - (23.1.1). The exceptions are the push_front and pop_front member - functions, which are not provided. Descriptions are pro- vided - here only for operations on vector that are not described in one - of these tables or for operations where there is additional - semantic information. - - I suggest, instead: - - ``iterator_facade`` is a base class template which implements the - interface of standard iterators in terms of a few core functions - and associated types, to be supplied by a derived iterator class. +``iterator_facade`` is a base class template which implements the +interface of standard iterators in terms of a few core functions +and associated types, to be supplied by a derived iterator class. Template class ``iterator_facade`` ---------------------------------- @@ -579,7 +559,7 @@ object of type ``X``, ``b`` and ``c`` are objects of type ``const X``, ``n`` is an object of ``X::difference_type``, ``y`` is a constant object of a single pass iterator type interoperable with X, and ``z`` is a constant object of a random access traversal iterator type -interoperable with X. +interoperable with ``X``. +----------------------------------------+----------------------------------------+-------------------------------------------------+-------------------------------------------+ | Expression | Return Type | Assertion/Note/Precondition/Postcondition | Required to implement Iterator Concept(s) | @@ -706,33 +686,15 @@ interoperable with X. Iterator adaptor [lib.iterator.adaptor] ======================================= -.. Jeremy, the same argument about appropriateness applies here as well. +The ``iterator_adaptor`` is a base class template which is a derived +class of ``iterator_facade``. The core interface functions expected by +``iterator_facade`` are implemented in terms of the ``Base`` template +parameter. A class derived from ``iterator_adaptor`` typically +overrides some of the (non-vertual) core interface functions to adapt +the behaviour of the iterator. The ``Base`` type need not meet the +full requirements for an iterator. It need only support the operations +that are not overriden by the users derived class. -A common pattern of iterator construction is the adaptation of one -iterator to form a new one. The functionality of an iterator is -composed of four orthogonal aspects: traversal, indirection, equality -comparison, and distance measurement. Adapting an old iterator to -create a new one often saves work because one can change a few aspects -of the functionality while retaining the rest. For example, the -Standard provides ``reverse_iterator``, which adapts any Bidirectional -Iterator by inverting its direction of traversal. - -The ``iterator_adaptor`` class template fulfills the need for -constructing adaptors. Instantiations of ``iterator_adaptor`` serve -as a base classes for new iterators, providing the default behaviour -of forwarding all operations to the underlying iterator. The user can -selectively replace these features in the derived iterator class. - -The ``iterator_adaptor`` class template adapts a ``Base`` type to -create a new iterator ("base" here means the type being adapted). -The ``iterator_adaptor`` forwards all operations to an instance of the -``Base`` type, which it stores as a member. 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 [lib.iterator.facade]. The ``Base`` type need not meet -the full requirements for an iterator. It need only support the -operations that are not overriden by the users derived class. Template class ``iterator_adaptor`` ----------------------------------- @@ -756,21 +718,61 @@ Template class ``iterator_adaptor`` iterator_adaptor() {} explicit iterator_adaptor(Base iter); Base base() const; + protected: + // Default implementation of core interface for iterator_facade + typename super_t::reference dereference() const + { return *m_iterator; } + + template < + class OtherDerived, class OtherIterator, class V, class C, class R, class P, class D + > + bool equal(iterator_adaptor const& x) const + { + BOOST_STATIC_ASSERT( + (detail::same_category_and_difference::value) + ); + return m_iterator == x.base(); + } + void advance(typename super_t::difference_type n) + { + m_iterator += n; + } + + void increment() { ++m_iterator; } + void decrement() { --m_iterator; } + + template < + class OtherDerived, class OtherIterator, class V, class C, class R, class P, class D + > + typename super_t::difference_type distance_to( + iterator_adaptor const& y) const + { + BOOST_STATIC_ASSERT( + (detail::same_category_and_difference::value) + ); + return y.base() - m_iterator; + } + Base const& base_reference() const + { return m_iterator; } + + private: // exposition + Base m_iterator; }; ``iterator_adaptor`` requirements --------------------------------- -Write me. - -.. Make sure to mention that this words for both old and new +.. Make sure to mention that this works for both old and new style iterators. -JGS .. I'm not sure we should say that in the standard text; let other people add non-normative in editing if they feel the need ;-) -DWA +.. Well, we have to specify the requirements for the template + parameters such as ``Category``, so this will come up. -JGS + Specialized adaptors [lib.iterator.special.adaptors] ==================================================== @@ -871,6 +873,8 @@ indirect iterator. new categories. I think it only applies to the traversal part of the concept. +.. Address the above. -JGS + Reverse iterator ---------------- diff --git a/doc/new-iter-concepts.rst b/doc/new-iter-concepts.rst index c9a8060..ca1993a 100644 --- a/doc/new-iter-concepts.rst +++ b/doc/new-iter-concepts.rst @@ -579,39 +579,29 @@ pseudo-code. :: - inherit-category(access-tag, traversal-tag) = - (access-tag is convertible to readable_lvalue_iterator_tag - or access-tag is convertible to writable_lvalue_iterator_tag - ) - ? ( - (traversal-tag is convertible to random_access_traversal_tag) - ? random_access_iterator_tag - - : (traversal-tag is convertible to bidirectional_traversal_tag) - ? bidirectional_iterator_tag - - : (traversal-tag is convertible to forward_traversal_tag) - ? forward_iterator_tag - - : null_category_tag - ) - : (access-tag is convertible to readable_writable_iterator_tag - and traversal-tag is convertible to single_pass_iterator_tag) - ? input_output_iterator_tag - - : (access-tag is convertible to readable_iterator_tag - and traversal-tag is convertible to single_pass_iterator_tag) - ? input_iterator_tag - - : (access-tag is convertible to writable_iterator_tag - and traversal-tag is convertible to incrementable_iterator_tag) - ? output_iterator_tag - - : null_category_tag; - -.. Jeremy, I'm not attached to the rewrite above; I just did it to see - if I could make it clearer please feel free to rewrite if you don't - like it. + inherit-category(access-tag, traversal-tag) = + if (access-tag is convertible to readable_lvalue_iterator_tag + or access-tag is convertible to writable_lvalue_iterator_tag) { + if (traversal-tag is convertible to random_access_traversal_tag) + return random_access_iterator_tag; + else if (traversal-tag is convertible to bidirectional_traversal_tag) + return bidirectional_iterator_tag; + else if (traversal-tag is convertible to forward_traversal_tag) + return forward_iterator_tag; + else + return null_category_tag; + } else if (access-tag is convertible to readable_writable_iterator_tag + and traversal-tag is convertible to single_pass_iterator_tag) + return input_output_iterator_tag; + else if (access-tag is convertible to readable_iterator_tag + and traversal-tag is convertible to single_pass_iterator_tag) + return input_iterator_tag; + else if (access-tag is convertible to writable_iterator_tag + and traversal-tag is convertible to incrementable_iterator_tag) + return output_iterator_tag; + else + return null_category_tag; + The ``access_category`` and ``traversal_category`` class templates are traits classes. For iterators whose @@ -626,38 +616,38 @@ The following pseudo-code describes the algorithm. :: access-category(Iterator) = - cat = iterator_traits::iterator_category; - if (cat == iterator_tag) - return Access; - else if (cat is convertible to forward_iterator_tag) { - if (iterator_traits::reference is a const reference) - return readable_lvalue_iterator_tag; + cat = iterator_traits::iterator_category; + if (cat == iterator_tag) + return Access; + else if (cat is convertible to forward_iterator_tag) { + if (iterator_traits::reference is a const reference) + return readable_lvalue_iterator_tag; + else + return writable_lvalue_iterator_tag; + } else if (cat is convertible to input_iterator_tag) + return readable_iterator_tag; + else if (cat is convertible to output_iterator_tag) + return writable_iterator_tag; else - return writable_lvalue_iterator_tag; - } else if (cat is convertible to input_iterator_tag) - return readable_iterator_tag; - else if (cat is convertible to output_iterator_tag) - return writable_iterator_tag; - else - return null_category_tag; + return null_category_tag; traversal-category(Iterator) = - cat = iterator_traits::iterator_category; - if (cat == iterator_tag) - return Traversal; - else if (cat is convertible to random_access_iterator_tag) - return random_access_traversal_tag; - else if (cat is convertible to bidirectional_iterator_tag) - return bidirectional_traversal_tag; - else if (cat is convertible to forward_iterator_tag) - return forward_traversal_tag; - else if (cat is convertible to input_iterator_tag) - return single_pass_iterator_tag; - else if (cat is convertible to output_iterator_tag) - return incrementable_iterator_tag; - else - return null_category_tag; - }; + cat = iterator_traits::iterator_category; + if (cat == iterator_tag) + return Traversal; + else if (cat is convertible to random_access_iterator_tag) + return random_access_traversal_tag; + else if (cat is convertible to bidirectional_iterator_tag) + return bidirectional_traversal_tag; + else if (cat is convertible to forward_iterator_tag) + return forward_traversal_tag; + else if (cat is convertible to input_iterator_tag) + return single_pass_iterator_tag; + else if (cat is convertible to output_iterator_tag) + return incrementable_iterator_tag; + else + return null_category_tag; + The following specializations provide the access and traversal category tags for pointer types.