forked from boostorg/iterator
blah
[SVN r1187]
This commit is contained in:
@@ -361,6 +361,16 @@ Standard compliant iterators).
|
|||||||
Proposed Text
|
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 ``<iterator_helper>`` synopsis [lib.iterator.helper.synopsis]
|
Header ``<iterator_helper>`` synopsis [lib.iterator.helper.synopsis]
|
||||||
=======================================================================
|
=======================================================================
|
||||||
|
|
||||||
@@ -430,39 +440,9 @@ Header ``<iterator_helper>`` synopsis [lib.iterator.helper.synopsis]
|
|||||||
Iterator facade [lib.iterator.facade]
|
Iterator facade [lib.iterator.facade]
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
|
``iterator_facade`` is a base class template which implements the
|
||||||
The iterator requirements define a rich interface, containing many
|
interface of standard iterators in terms of a few core functions
|
||||||
redundant operators, so that using iterators is convenient. The
|
and associated types, to be supplied by a derived iterator class.
|
||||||
``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.
|
|
||||||
|
|
||||||
Template class ``iterator_facade``
|
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
|
``n`` is an object of ``X::difference_type``, ``y`` is a constant
|
||||||
object of a single pass iterator type interoperable with X, and ``z``
|
object of a single pass iterator type interoperable with X, and ``z``
|
||||||
is a constant object of a random access traversal iterator type
|
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) |
|
| 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]
|
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``
|
Template class ``iterator_adaptor``
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
@@ -756,21 +718,61 @@ Template class ``iterator_adaptor``
|
|||||||
iterator_adaptor() {}
|
iterator_adaptor() {}
|
||||||
explicit iterator_adaptor(Base iter);
|
explicit iterator_adaptor(Base iter);
|
||||||
Base base() const;
|
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<OtherDerived, OtherIterator, V, C, R, P, D> const& x) const
|
||||||
|
{
|
||||||
|
BOOST_STATIC_ASSERT(
|
||||||
|
(detail::same_category_and_difference<Derived,OtherDerived>::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<OtherDerived, OtherIterator, V, C, R, P, D> const& y) const
|
||||||
|
{
|
||||||
|
BOOST_STATIC_ASSERT(
|
||||||
|
(detail::same_category_and_difference<Derived,OtherDerived>::value)
|
||||||
|
);
|
||||||
|
return y.base() - m_iterator;
|
||||||
|
}
|
||||||
|
Base const& base_reference() const
|
||||||
|
{ return m_iterator; }
|
||||||
|
|
||||||
|
private: // exposition
|
||||||
|
Base m_iterator;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
``iterator_adaptor`` requirements
|
``iterator_adaptor`` requirements
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
|
||||||
Write me.
|
.. Make sure to mention that this works for both old and new
|
||||||
|
|
||||||
.. Make sure to mention that this words for both old and new
|
|
||||||
style iterators. -JGS
|
style iterators. -JGS
|
||||||
|
|
||||||
.. I'm not sure we should say that in the standard text; let other
|
.. 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
|
people add non-normative in editing if they feel the need
|
||||||
;-) -DWA
|
;-) -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]
|
Specialized adaptors [lib.iterator.special.adaptors]
|
||||||
====================================================
|
====================================================
|
||||||
|
|
||||||
@@ -871,6 +873,8 @@ indirect iterator.
|
|||||||
new categories. I think it only applies to the traversal part of
|
new categories. I think it only applies to the traversal part of
|
||||||
the concept.
|
the concept.
|
||||||
|
|
||||||
|
.. Address the above. -JGS
|
||||||
|
|
||||||
Reverse iterator
|
Reverse iterator
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
@@ -579,39 +579,29 @@ pseudo-code.
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
inherit-category(access-tag, traversal-tag) =
|
inherit-category(access-tag, traversal-tag) =
|
||||||
(access-tag is convertible to readable_lvalue_iterator_tag
|
if (access-tag is convertible to readable_lvalue_iterator_tag
|
||||||
or access-tag is convertible to writable_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;
|
||||||
(traversal-tag is convertible to random_access_traversal_tag)
|
else if (traversal-tag is convertible to bidirectional_traversal_tag)
|
||||||
? random_access_iterator_tag
|
return bidirectional_iterator_tag;
|
||||||
|
else if (traversal-tag is convertible to forward_traversal_tag)
|
||||||
: (traversal-tag is convertible to bidirectional_traversal_tag)
|
return forward_iterator_tag;
|
||||||
? bidirectional_iterator_tag
|
else
|
||||||
|
return null_category_tag;
|
||||||
: (traversal-tag is convertible to forward_traversal_tag)
|
} else if (access-tag is convertible to readable_writable_iterator_tag
|
||||||
? forward_iterator_tag
|
and traversal-tag is convertible to single_pass_iterator_tag)
|
||||||
|
return input_output_iterator_tag;
|
||||||
: null_category_tag
|
else if (access-tag is convertible to readable_iterator_tag
|
||||||
)
|
and traversal-tag is convertible to single_pass_iterator_tag)
|
||||||
: (access-tag is convertible to readable_writable_iterator_tag
|
return input_iterator_tag;
|
||||||
and traversal-tag is convertible to single_pass_iterator_tag)
|
else if (access-tag is convertible to writable_iterator_tag
|
||||||
? input_output_iterator_tag
|
and traversal-tag is convertible to incrementable_iterator_tag)
|
||||||
|
return output_iterator_tag;
|
||||||
: (access-tag is convertible to readable_iterator_tag
|
else
|
||||||
and traversal-tag is convertible to single_pass_iterator_tag)
|
return null_category_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.
|
|
||||||
|
|
||||||
The ``access_category`` and ``traversal_category`` class templates are
|
The ``access_category`` and ``traversal_category`` class templates are
|
||||||
traits classes. For iterators whose
|
traits classes. For iterators whose
|
||||||
@@ -626,38 +616,38 @@ The following pseudo-code describes the algorithm.
|
|||||||
::
|
::
|
||||||
|
|
||||||
access-category(Iterator) =
|
access-category(Iterator) =
|
||||||
cat = iterator_traits<Iterator>::iterator_category;
|
cat = iterator_traits<Iterator>::iterator_category;
|
||||||
if (cat == iterator_tag<Access,Traversal>)
|
if (cat == iterator_tag<Access,Traversal>)
|
||||||
return Access;
|
return Access;
|
||||||
else if (cat is convertible to forward_iterator_tag) {
|
else if (cat is convertible to forward_iterator_tag) {
|
||||||
if (iterator_traits<Iterator>::reference is a const reference)
|
if (iterator_traits<Iterator>::reference is a const reference)
|
||||||
return readable_lvalue_iterator_tag;
|
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
|
else
|
||||||
return writable_lvalue_iterator_tag;
|
return null_category_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;
|
|
||||||
|
|
||||||
traversal-category(Iterator) =
|
traversal-category(Iterator) =
|
||||||
cat = iterator_traits<Iterator>::iterator_category;
|
cat = iterator_traits<Iterator>::iterator_category;
|
||||||
if (cat == iterator_tag<Access,Traversal>)
|
if (cat == iterator_tag<Access,Traversal>)
|
||||||
return Traversal;
|
return Traversal;
|
||||||
else if (cat is convertible to random_access_iterator_tag)
|
else if (cat is convertible to random_access_iterator_tag)
|
||||||
return random_access_traversal_tag;
|
return random_access_traversal_tag;
|
||||||
else if (cat is convertible to bidirectional_iterator_tag)
|
else if (cat is convertible to bidirectional_iterator_tag)
|
||||||
return bidirectional_traversal_tag;
|
return bidirectional_traversal_tag;
|
||||||
else if (cat is convertible to forward_iterator_tag)
|
else if (cat is convertible to forward_iterator_tag)
|
||||||
return forward_traversal_tag;
|
return forward_traversal_tag;
|
||||||
else if (cat is convertible to input_iterator_tag)
|
else if (cat is convertible to input_iterator_tag)
|
||||||
return single_pass_iterator_tag;
|
return single_pass_iterator_tag;
|
||||||
else if (cat is convertible to output_iterator_tag)
|
else if (cat is convertible to output_iterator_tag)
|
||||||
return incrementable_iterator_tag;
|
return incrementable_iterator_tag;
|
||||||
else
|
else
|
||||||
return null_category_tag;
|
return null_category_tag;
|
||||||
};
|
|
||||||
|
|
||||||
The following specializations provide the access and traversal
|
The following specializations provide the access and traversal
|
||||||
category tags for pointer types.
|
category tags for pointer types.
|
||||||
|
Reference in New Issue
Block a user