forked from boostorg/iterator
added a bunch for the specialized adaptors,
also filled out the facade and adaptor sections [SVN r1181]
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
: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
|
||||||
: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
|
||||||
|
|
||||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
|
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
|
||||||
|
|
||||||
:abstract: We propose a set of class templates that help programmers
|
:abstract: We propose a set of class templates that help programmers
|
||||||
build standard-conforming iterators and to build iterators
|
build standard-conforming iterators and iterators
|
||||||
that adapt other iterators.
|
that adapt other iterators.
|
||||||
|
|
||||||
.. contents:: Table of Contents
|
.. contents:: Table of Contents
|
||||||
@@ -121,12 +121,12 @@ Iterator Concepts.
|
|||||||
Interoperability
|
Interoperability
|
||||||
================
|
================
|
||||||
|
|
||||||
The question of iterator interoperability is poorly adressed in the current standard.
|
The question of iterator interoperability is poorly adressed in the
|
||||||
There are currently two defect reports that are concerned with interoperability
|
current standard. There are currently two defect reports that are
|
||||||
issues.
|
concerned with interoperability issues.
|
||||||
|
|
||||||
Issue `179`_ concerns the fact that mutable container iterator types
|
Issue `179`_ concerns the fact that mutable container iterator types
|
||||||
are only required to be convertible the corresponding constant
|
are only required to be convertible to the corresponding constant
|
||||||
iterator types, but objects of these types are not required to
|
iterator types, but objects of these types are not required to
|
||||||
interoperate in comparison or subtraction expressions. This situation
|
interoperate in comparison or subtraction expressions. This situation
|
||||||
is tedious in practice and out of line with the way built in types
|
is tedious in practice and out of line with the way built in types
|
||||||
@@ -161,7 +161,8 @@ identified the following core behaviors for iterators:
|
|||||||
|
|
||||||
In addition to the behaviors listed above, the core interface elements
|
In addition to the behaviors listed above, the core interface elements
|
||||||
include the associated types exposed through iterator traits:
|
include the associated types exposed through iterator traits:
|
||||||
``value_type``, ``reference``, ``pointer``, and ``iterator_category``.
|
``value_type``, ``reference``, ``pointer``, ``difference_type``, and
|
||||||
|
``iterator_category``.
|
||||||
|
|
||||||
Iterator facade uses the Curiously Recurring Template Pattern (CRTP)
|
Iterator facade uses the Curiously Recurring Template Pattern (CRTP)
|
||||||
[Cop95]_ so that the user can specifiy the behaviour of
|
[Cop95]_ so that the user can specifiy the behaviour of
|
||||||
@@ -222,43 +223,47 @@ interoperable with X.
|
|||||||
| | |>= c``. | |
|
| | |>= c``. | |
|
||||||
+----------------------------------------+----------------------------------------+-------------------------------------------------+-------------------------------------------+
|
+----------------------------------------+----------------------------------------+-------------------------------------------------+-------------------------------------------+
|
||||||
|
|
||||||
.. Should we add a comment that a zero overhead implementation of iterator_facade
|
.. Should we add a comment that a zero overhead implementation of iterator_facade
|
||||||
is possible with proper inlining?
|
is possible with proper inlining?
|
||||||
|
|
||||||
|
.. Would this be a good place to talk about constructors? -JGS
|
||||||
|
|
||||||
Iterator Core Access
|
Iterator Core Access
|
||||||
====================
|
====================
|
||||||
|
|
||||||
``iterator_facade`` and the operator implementations need to be able
|
``iterator_facade`` and the operator implementations need to be able
|
||||||
to access the core interface member functions in the derived class.
|
to access the core member functions in the derived class. Making the
|
||||||
Making the core interface member funtions public would expose an
|
core member funtions public would expose an implementation detail to
|
||||||
implementation detail to the user. This proposal frees the public
|
the user. This proposal frees the public interface of the derived
|
||||||
interface of the derived iterator type from any implementation detail.
|
iterator type from any implementation detail.
|
||||||
|
|
||||||
Preventing direct access to the core interface has two advantages.
|
Preventing direct access to the core member functions has two
|
||||||
First, there is no possibility for the user to accidently use a member
|
advantages. First, there is no possibility for the user to accidently
|
||||||
function of the iterator when a member of the value_type was intended.
|
use a member function of the iterator when a member of the value_type
|
||||||
This has been an issue with smart pointer implementations in the past.
|
was intended. This has been an issue with smart pointer
|
||||||
The second and main advantage is that library implementers can freely
|
implementations in the past. The second and main advantage is that
|
||||||
exchange a hand-rolled iterator implementation for one based on
|
library implementers can freely exchange a hand-rolled iterator
|
||||||
``iterator_facade`` without fear of breaking code that was accessing
|
implementation for one based on ``iterator_facade`` without fear of
|
||||||
the public core interface directly.
|
breaking code that was accessing the public core member functions
|
||||||
|
directly.
|
||||||
|
|
||||||
In a naive implementation, keeping the derived class' core interface
|
In a naive implementation, keeping the derived class' core member
|
||||||
private would require it to grant friendship to ``iterator_facade``
|
functions private would require it to grant friendship to
|
||||||
and each of the seven operators. In order to reduce the burden of
|
``iterator_facade`` and each of the seven operators. In order to
|
||||||
limiting access, this proposal provides ``iterator_core_access``, a
|
reduce the burden of limiting access, this proposal provides
|
||||||
class that acts as a gateway to the core interface in the derived
|
``iterator_core_access``, a class that acts as a gateway to the core
|
||||||
iterator class. The author of the derived class only needs to grant
|
member functions in the derived iterator class. The author of the
|
||||||
friendship to ``iterator_core_access`` to make his core interface
|
derived class only needs to grant friendship to
|
||||||
available to the library.
|
``iterator_core_access`` to make his core member functions available
|
||||||
|
to the library.
|
||||||
|
|
||||||
``iterator_core_access`` would be typically implemented as an empty
|
``iterator_core_access`` would be typically implemented as an empty
|
||||||
class containing only static member functions which invoke the
|
class containing only static member functions which invoke the
|
||||||
iterator core interface. There is, however, no need to standardize the
|
iterator core member functions. There is, however, no need to
|
||||||
gateway protocol.
|
standardize the gateway protocol.
|
||||||
|
|
||||||
It is important to note that ``iterator_core_access`` does not open a
|
It is important to note that ``iterator_core_access`` does not open a
|
||||||
safety loophole, as every function in the core interface preserves the
|
safety loophole, as every core member function preserves the
|
||||||
invariants of the iterator.
|
invariants of the iterator.
|
||||||
|
|
||||||
Iterator Adaptor
|
Iterator Adaptor
|
||||||
@@ -279,7 +284,11 @@ instance of the ``Base`` type, which it stores as a member.
|
|||||||
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 overrides
|
||||||
some of the core operations by implementing the (non-virtual) member
|
some of the core operations by implementing the (non-virtual) member
|
||||||
functions described in the table above.
|
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 overriden by the
|
||||||
|
users derived class.
|
||||||
|
|
||||||
|
|
||||||
.. In addition, the derived
|
.. In addition, the derived
|
||||||
class will typically need to define some constructors.
|
class will typically need to define some constructors.
|
||||||
@@ -321,8 +330,8 @@ which were easily implemented using ``iterator_adaptor``:
|
|||||||
|
|
||||||
Based on examples in the Boost library, users have generated many new
|
Based on examples in the Boost library, users have generated many new
|
||||||
adaptors, among them a permutation adaptor which applies some
|
adaptors, among them a permutation adaptor which applies some
|
||||||
permutation to a RandomAccessIterator, and a strided adaptor, which
|
permutation to a Random Access Iterator, and a strided adaptor, which
|
||||||
adapts a RandomAccessIterator by multiplying its unit of motion by a
|
adapts a Random Access Iterator by multiplying its unit of motion by a
|
||||||
constant factor. In addition, the Boost Graph Library (BGL) uses
|
constant factor. In addition, the Boost Graph Library (BGL) uses
|
||||||
iterator adaptors to adapt other graph libraries, such as LEDA [10]
|
iterator adaptors to adapt other graph libraries, such as LEDA [10]
|
||||||
and Stanford GraphBase [8], to the BGL interface (which requires C++
|
and Stanford GraphBase [8], to the BGL interface (which requires C++
|
||||||
@@ -332,51 +341,95 @@ Standard compliant iterators).
|
|||||||
Proposed Text
|
Proposed Text
|
||||||
===============
|
===============
|
||||||
|
|
||||||
|
Header ``<iterator_helper>`` synopsis [lib.iterator.helper.synopsis]
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
.. How's that for a name for the header? -JGS
|
||||||
|
.. Also, below I changed "not_specified" to the user-centric "use_default" -JGS
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
struct not_specified { };
|
struct use_default { };
|
||||||
|
|
||||||
struct iterator_core_access { /* implementation detail */ };
|
struct iterator_core_access { /* implementation detail */ };
|
||||||
|
|
||||||
template <
|
template <
|
||||||
class Derived
|
class Derived
|
||||||
, class Value = not_specified
|
, class Value = use_default
|
||||||
, class Category = not_specified
|
, class Category = use_default
|
||||||
, class Reference = not_specified
|
, class Reference = use_default
|
||||||
, class Pointer = not_specified
|
, class Pointer = use_default
|
||||||
, class Difference = not_specified
|
, class Difference = use_default
|
||||||
>
|
>
|
||||||
class iterator_facade;
|
class iterator_facade;
|
||||||
|
|
||||||
template <
|
template <
|
||||||
class Derived
|
class Derived
|
||||||
, class Base
|
, class Base
|
||||||
, class Value = not_specified
|
, class Value = use_default
|
||||||
, class Category = not_specified
|
, class Category = use_default
|
||||||
, class Reference = not_specified
|
, class Reference = use_default
|
||||||
, class Pointer = not_specified
|
, class Pointer = use_default
|
||||||
, class Difference = not_specified
|
, class Difference = use_default
|
||||||
>
|
>
|
||||||
class iterator_adaptor;
|
class iterator_adaptor;
|
||||||
|
|
||||||
|
template <
|
||||||
|
class Iterator
|
||||||
|
, class Value = use_default
|
||||||
|
, class Category = use_default
|
||||||
|
, class Reference = use_default
|
||||||
|
, class Pointer = use_default
|
||||||
|
, class Difference = use_default
|
||||||
|
>
|
||||||
|
class indirect_iterator;
|
||||||
|
|
||||||
|
template <class Iterator>
|
||||||
|
class reverse_iterator;
|
||||||
|
|
||||||
|
template <class AdaptableUnaryFunction, class Iterator>
|
||||||
|
class transform_iterator;
|
||||||
|
|
||||||
|
template <class Predicate, class Iterator>
|
||||||
|
class filter_iterator;
|
||||||
|
|
||||||
|
template <
|
||||||
|
class Incrementable,
|
||||||
|
class Category = use_default,
|
||||||
|
class Difference = use_default
|
||||||
|
>
|
||||||
|
class counting_iterator
|
||||||
|
|
||||||
|
template <class UnaryFunction>
|
||||||
|
class function_output_iterator;
|
||||||
|
|
||||||
|
|
||||||
``iterator_facade``
|
|
||||||
===================
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Template class ``iterator_facade``
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
template <
|
template <
|
||||||
class Derived
|
class Derived
|
||||||
, class Value = not_specified
|
, class Value = use_default
|
||||||
, class Category = not_specified
|
, class Category = use_default
|
||||||
, class Reference = not_specified
|
, class Reference = use_default
|
||||||
, class Pointer = not_specified
|
, class Pointer = use_default
|
||||||
, class Difference = not_specified
|
, class Difference = use_default
|
||||||
>
|
>
|
||||||
class iterator_facade {
|
class iterator_facade {
|
||||||
public:
|
public:
|
||||||
@@ -387,8 +440,8 @@ Standard compliant iterators).
|
|||||||
typedef ... iterator_category;
|
typedef ... iterator_category;
|
||||||
|
|
||||||
reference operator*() const;
|
reference operator*() const;
|
||||||
<see details> operator->() const;
|
/* see details */ operator->() const;
|
||||||
<see details> operator[](difference_type n) const;
|
/* see details */ operator[](difference_type n) const;
|
||||||
Derived& operator++();
|
Derived& operator++();
|
||||||
Derived operator++(int);
|
Derived operator++(int);
|
||||||
Derived& operator--();
|
Derived& operator--();
|
||||||
@@ -456,6 +509,63 @@ Standard compliant iterators).
|
|||||||
|
|
||||||
.. nothing
|
.. nothing
|
||||||
|
|
||||||
|
|
||||||
|
``iterator_facade`` requirements
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
The ``Derived`` template parameter must be the class deriving from
|
||||||
|
``iterator_facade``.
|
||||||
|
|
||||||
|
.. We need to describe how the defaults work and what
|
||||||
|
the typedefs come out to. -JGS
|
||||||
|
|
||||||
|
|
||||||
|
The following table describes the requirements on the type deriving
|
||||||
|
from the ``iterator_facade``. The expressions listed in the table are
|
||||||
|
required to be valid depending on the category of the derived iterator
|
||||||
|
type.
|
||||||
|
|
||||||
|
In the table below, ``X`` is the derived iterator type, ``a`` is an
|
||||||
|
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.
|
||||||
|
|
||||||
|
+----------------------------------------+----------------------------------------+-------------------------------------------------+-------------------------------------------+
|
||||||
|
| Expression | Return Type | Assertion/Note/Precondition/Postcondition | Required to implement Iterator Concept(s) |
|
||||||
|
| | | | |
|
||||||
|
+========================================+========================================+=================================================+===========================================+
|
||||||
|
| ``c.dereference()`` | ``X::reference`` | | Readable Iterator, Writable Iterator |
|
||||||
|
+----------------------------------------+----------------------------------------+-------------------------------------------------+-------------------------------------------+
|
||||||
|
| ``c.equal(b)`` | convertible to bool |true iff ``b`` and ``c`` are equivalent. | Single Pass Iterator |
|
||||||
|
+----------------------------------------+----------------------------------------+-------------------------------------------------+-------------------------------------------+
|
||||||
|
| ``c.equal(y)`` | convertible to bool |true iff ``c`` and ``y`` refer to the same | Single Pass Iterator |
|
||||||
|
| | |position. Implements ``c == y`` and ``c != y``. | |
|
||||||
|
+----------------------------------------+----------------------------------------+-------------------------------------------------+-------------------------------------------+
|
||||||
|
| ``a.advance(n)`` | unused | | Random Access Traversal Iterator |
|
||||||
|
+----------------------------------------+----------------------------------------+-------------------------------------------------+-------------------------------------------+
|
||||||
|
| ``a.increment()`` | unused | | Incrementable Iterator |
|
||||||
|
+----------------------------------------+----------------------------------------+-------------------------------------------------+-------------------------------------------+
|
||||||
|
| ``a.decrement()`` | unused | | Bidirectional Traversal Iterator |
|
||||||
|
+----------------------------------------+----------------------------------------+-------------------------------------------------+-------------------------------------------+
|
||||||
|
| ``c.distance_to(b)`` | convertible to X::difference_type | equivalent to ``distance(c, b)`` | Random Access Traversal Iterator |
|
||||||
|
+----------------------------------------+----------------------------------------+-------------------------------------------------+-------------------------------------------+
|
||||||
|
| ``c.distance_to(z)`` | convertible to X::difference_type |equivalent to ``distance(c, z)``. Implements ``c| Random Access Traversal Iterator |
|
||||||
|
| | |- z``, ``c < z``, ``c <= z``, ``c > z``, and ``c | |
|
||||||
|
| | |>= c``. | |
|
||||||
|
+----------------------------------------+----------------------------------------+-------------------------------------------------+-------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
.. We should explain more about how the
|
||||||
|
functions in the interface of iterator_facade
|
||||||
|
are there conditionally. -JGS
|
||||||
|
|
||||||
|
|
||||||
|
``iterator_facade`` operations
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
|
||||||
``reference operator*() const;``
|
``reference operator*() const;``
|
||||||
|
|
||||||
:Returns: ``static_cast<Derived const*>(this)->dereference();``
|
:Returns: ``static_cast<Derived const*>(this)->dereference();``
|
||||||
@@ -544,19 +654,50 @@ Standard compliant iterators).
|
|||||||
:Complexity:
|
:Complexity:
|
||||||
|
|
||||||
|
|
||||||
``iterator_adaptor``
|
Iterator adaptor [lib.iterator.adaptor]
|
||||||
====================
|
=======================================
|
||||||
|
|
||||||
|
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 reuse one aspect of
|
||||||
|
functionality while redefining the other. 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 deriving
|
||||||
|
class 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 <
|
template <
|
||||||
class Derived
|
class Derived
|
||||||
, class Base
|
, class Base
|
||||||
, class Value = not_specified
|
, class Value = use_default
|
||||||
, class Category = not_specified
|
, class Category = use_default
|
||||||
, class Reference = not_specified
|
, class Reference = use_default
|
||||||
, class Pointer = not_specified
|
, class Pointer = use_default
|
||||||
, class Difference = not_specified
|
, class Difference = use_default
|
||||||
>
|
>
|
||||||
class iterator_adaptor : public iterator_facade<Derived, /*impl detail ...*/> {
|
class iterator_adaptor : public iterator_facade<Derived, /*impl detail ...*/> {
|
||||||
public:
|
public:
|
||||||
@@ -566,8 +707,326 @@ Standard compliant iterators).
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
``iterator_adaptor`` requirements
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
Write me.
|
||||||
|
|
||||||
|
.. Make sure to mention that this words for both old and new
|
||||||
|
style iterators. -JGS
|
||||||
|
|
||||||
|
|
||||||
|
Specialized adaptors [lib.iterator.special.adaptors]
|
||||||
|
====================================================
|
||||||
|
|
||||||
|
|
||||||
|
Indirect iterator
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
The indirect iterator adapts an iterator by applying an *extra*
|
||||||
|
dereference inside of ``operator*()``. For example, this iterator
|
||||||
|
adaptor makes it possible to view a container of pointers
|
||||||
|
(e.g. ``list<foo*>``) as if it were a container of the pointed-to type
|
||||||
|
(e.g. ``list<foo>``) .
|
||||||
|
|
||||||
|
|
||||||
|
Template class ``indirect_iterator``
|
||||||
|
++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
template <
|
||||||
|
class Iterator
|
||||||
|
, class Value = use_default
|
||||||
|
, class Category = use_default
|
||||||
|
, class Reference = use_default
|
||||||
|
, class Pointer = use_default
|
||||||
|
, class Difference = use_default
|
||||||
|
>
|
||||||
|
class indirect_iterator
|
||||||
|
: public iterator_adaptor</* see discussion */>
|
||||||
|
{
|
||||||
|
typedef iterator_adaptor</* see discussion */> super_t;
|
||||||
|
friend class iterator_core_access;
|
||||||
|
public:
|
||||||
|
indirect_iterator() {}
|
||||||
|
|
||||||
|
indirect_iterator(Iterator iter)
|
||||||
|
: super_t(iter) {}
|
||||||
|
|
||||||
|
template <
|
||||||
|
class Iterator2, class Value2, class Category2
|
||||||
|
, class Reference2, class Pointer2, class Difference2
|
||||||
|
>
|
||||||
|
indirect_iterator(
|
||||||
|
indirect_iterator<
|
||||||
|
Iterator2, Value2, Category2, Reference2, Pointer2, Difference2
|
||||||
|
> const& y
|
||||||
|
, typename enable_if_convertible<Iterator2, Iterator>::type* = 0
|
||||||
|
)
|
||||||
|
: super_t(y.base())
|
||||||
|
{}
|
||||||
|
|
||||||
|
private:
|
||||||
|
typename super_t::reference dereference() const
|
||||||
|
{
|
||||||
|
return **this->base();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
``indirect_iterator`` requirements
|
||||||
|
++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
The ``value_type`` of the ``Iterator`` template parameter should
|
||||||
|
itself be dereferenceable. The return type of the ``operator*`` for
|
||||||
|
the ``value_type`` must be the same type as the ``Reference`` template
|
||||||
|
parameter. The ``Value`` template parameter will be the ``value_type``
|
||||||
|
for the ``indirect_iterator``, unless ``Value`` is const. If ``Value``
|
||||||
|
is ``const X``, then ``value_type`` will be *non-* ``const X``. The
|
||||||
|
default for ``Value`` is
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
iterator_traits< iterator_traits<Iterator>::value_type >::value_type
|
||||||
|
|
||||||
|
If the default is used for ``Value``, then there must be a valid
|
||||||
|
specialization of ``iterator_traits`` for the value type of the base
|
||||||
|
iterator.
|
||||||
|
|
||||||
|
The ``Reference`` parameter will be the ``reference`` type of the
|
||||||
|
``indirect_iterator``. The default is ``Value&``.
|
||||||
|
|
||||||
|
The ``Pointer`` parameter will be the ``pointer`` type of the
|
||||||
|
``indirect_iterator``. The default is ``Value*``.
|
||||||
|
|
||||||
|
The ``Category`` parameter is the ``iterator_category`` type for the
|
||||||
|
``indirect_iterator``. The default is
|
||||||
|
``iterator_traits<Iterator>::iterator_category``.
|
||||||
|
|
||||||
|
The indirect iterator will model whichever standard iterator concepts
|
||||||
|
are modeled by the base iterator. For example, if the base iterator is
|
||||||
|
a model of Random Access Traversal Iterator then so is the resulting
|
||||||
|
indirect iterator.
|
||||||
|
|
||||||
|
|
||||||
|
Reverse iterator
|
||||||
|
----------------
|
||||||
|
|
||||||
|
The reverse iterator adaptor flips the direction of a base iterator's
|
||||||
|
motion. Invoking ``operator++()`` moves the base iterator backward and
|
||||||
|
invoking ``operator--()`` moves the base iterator forward. The Boost
|
||||||
|
reverse iterator adaptor is better to use than the
|
||||||
|
``std::reverse_iterator`` class in situations where pairs of
|
||||||
|
mutable/constant iterators are needed (e.g., in containers) because
|
||||||
|
comparisons and conversions between the mutable and const versions are
|
||||||
|
implemented correctly.
|
||||||
|
|
||||||
|
Template class ``reverse_iterator``
|
||||||
|
+++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
template <class Iterator>
|
||||||
|
class reverse_iterator :
|
||||||
|
public iterator_adaptor< reverse_iterator<Iterator>, Iterator >
|
||||||
|
{
|
||||||
|
typedef iterator_adaptor< reverse_iterator<Iterator>, Iterator > super_t;
|
||||||
|
friend class iterator_core_access;
|
||||||
|
public:
|
||||||
|
reverse_iterator() {}
|
||||||
|
|
||||||
|
explicit reverse_iterator(Iterator x)
|
||||||
|
: super_t(x) {}
|
||||||
|
|
||||||
|
template<class OtherIterator>
|
||||||
|
reverse_iterator(
|
||||||
|
reverse_iterator<OtherIterator> const& r
|
||||||
|
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
|
||||||
|
)
|
||||||
|
: super_t(r.base())
|
||||||
|
{}
|
||||||
|
|
||||||
|
private: /* exposition */
|
||||||
|
typename super_t::reference dereference() const { return *prior(this->base()); }
|
||||||
|
|
||||||
|
void increment() { super_t::decrement(); }
|
||||||
|
void decrement() { super_t::increment(); }
|
||||||
|
|
||||||
|
void advance(typename super_t::difference_type n)
|
||||||
|
{
|
||||||
|
super_t::advance(-n);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class OtherIterator>
|
||||||
|
typename super_t::difference_type
|
||||||
|
distance_to(reverse_iterator<OtherIterator> const& y) const
|
||||||
|
{
|
||||||
|
return -super_t::distance_to(y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
``reverse_iterator`` requirements
|
||||||
|
+++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
The base iterator must be a model of Bidirectional Traversal
|
||||||
|
Iterator. The reverse iterator will model whichever standard iterator
|
||||||
|
concepts are modeled by the base iterator. For example, if the base
|
||||||
|
iterator is a model of Random Access Traversal Iterator then so is the
|
||||||
|
resulting reverse iterator.
|
||||||
|
|
||||||
|
|
||||||
|
Transform iterator
|
||||||
|
------------------
|
||||||
|
|
||||||
|
The transform iterator adapts an iterator by applying some function
|
||||||
|
object to the result of dereferencing the iterator. In other words,
|
||||||
|
the ``operator*`` of the transform iterator first dereferences the
|
||||||
|
base iterator, passes the result of this to the function object, and
|
||||||
|
then returns the result.
|
||||||
|
|
||||||
|
|
||||||
|
Template class ``transform_iterator``
|
||||||
|
+++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
template <class AdaptableUnaryFunction, class Iterator>
|
||||||
|
class transform_iterator
|
||||||
|
: public iterator_adaptor</* see discussion */>
|
||||||
|
{
|
||||||
|
typedef iterator_adaptor</* see discussion */> super_t;
|
||||||
|
friend class iterator_core_access;
|
||||||
|
public:
|
||||||
|
transform_iterator() { }
|
||||||
|
|
||||||
|
transform_iterator(Iterator const& x, AdaptableUnaryFunction f)
|
||||||
|
: super_t(x), m_f(f) { }
|
||||||
|
|
||||||
|
template<class OtherIterator>
|
||||||
|
transform_iterator(
|
||||||
|
transform_iterator<AdaptableUnaryFunction, OtherIterator> const& t
|
||||||
|
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
|
||||||
|
)
|
||||||
|
: super_t(t.base()), m_f(t.functor()) {}
|
||||||
|
|
||||||
|
AdaptableUnaryFunction functor() const
|
||||||
|
{ return m_f; }
|
||||||
|
|
||||||
|
private: /* exposition */
|
||||||
|
typename super_t::value_type dereference() const
|
||||||
|
{ return m_f(super_t::dereference()); }
|
||||||
|
|
||||||
|
AdaptableUnaryFunction m_f;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
``transform_iterator`` requirements
|
||||||
|
+++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
Write me. Use ``result_of``?
|
||||||
|
|
||||||
|
|
||||||
|
Filter iterator
|
||||||
|
---------------
|
||||||
|
|
||||||
|
The filter iterator adaptor creates a view of an iterator range in
|
||||||
|
which some elements of the range are skipped over. A predicate
|
||||||
|
function object controls which elements are skipped. When the
|
||||||
|
predicate is applied to an element, if it returns ``true`` then the
|
||||||
|
element is retained and if it returns ``false`` then the element is
|
||||||
|
skipped over.
|
||||||
|
|
||||||
|
|
||||||
|
Template class ``filter_iterator``
|
||||||
|
++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
template <class Predicate, class Iterator>
|
||||||
|
class filter_iterator
|
||||||
|
: public iterator_adaptor<
|
||||||
|
filter_iterator<Predicate, Iterator>, Iterator
|
||||||
|
, use_default
|
||||||
|
, /* see details */
|
||||||
|
>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
filter_iterator() { }
|
||||||
|
filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
|
||||||
|
filter_iterator(Iterator x, Iterator end = Iterator());
|
||||||
|
template<class OtherIterator>
|
||||||
|
filter_iterator(
|
||||||
|
filter_iterator<Predicate, OtherIterator> const& t
|
||||||
|
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
|
||||||
|
);
|
||||||
|
Predicate predicate() const;
|
||||||
|
Iterator end() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Counting iterator
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
|
||||||
|
Template class ``counting_iterator``
|
||||||
|
++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
template <class Incrementable, class Category = not_specified, class Difference = not_specified>
|
||||||
|
class counting_iterator
|
||||||
|
: public iterator_adaptor</* see details */>
|
||||||
|
{
|
||||||
|
typedef iterator_adaptor</* see details */> super_t;
|
||||||
|
friend class iterator_core_access;
|
||||||
|
public:
|
||||||
|
counting_iterator();
|
||||||
|
counting_iterator(counting_iterator const& rhs);
|
||||||
|
counting_iterator(Incrementable x);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Function output iterator
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
The function output iterator adaptor makes it easier to create custom
|
||||||
|
output iterators. The adaptor takes a unary function and creates a
|
||||||
|
model of Output Iterator. Each item assigned to the output iterator is
|
||||||
|
passed as an argument to the unary function. The motivation for this
|
||||||
|
iterator is that creating a conforming output iterator is non-trivial,
|
||||||
|
particularly because the proper implementation usually requires a
|
||||||
|
proxy object.
|
||||||
|
|
||||||
|
|
||||||
|
Template class ``function_output_iterator``
|
||||||
|
+++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
template <class UnaryFunction>
|
||||||
|
class function_output_iterator {
|
||||||
|
public:
|
||||||
|
typedef std::output_iterator_tag iterator_category;
|
||||||
|
typedef void value_type;
|
||||||
|
typedef void difference_type;
|
||||||
|
typedef void pointer;
|
||||||
|
typedef void reference;
|
||||||
|
|
||||||
|
explicit function_output_iterator(const UnaryFunction& f = UnaryFunction())
|
||||||
|
: m_f(f) {}
|
||||||
|
|
||||||
|
struct output_proxy {
|
||||||
|
output_proxy(UnaryFunction& f);
|
||||||
|
template <class T> output_proxy& operator=(const T& value);
|
||||||
|
};
|
||||||
|
output_proxy operator*();
|
||||||
|
function_output_iterator& operator++();
|
||||||
|
function_output_iterator& operator++(int);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
.. [Cop95] [Coplien, 1995] Coplien, J., Curiously Recurring Template
|
.. [Cop95] [Coplien, 1995] Coplien, J., Curiously Recurring Template
|
||||||
Patterns, C ++Report, February 1995, pp. 24-27.
|
Patterns, C++ Report, February 1995, pp. 24-27.
|
||||||
|
@@ -230,7 +230,7 @@ combined into a single type using the following `iterator_tag` class.
|
|||||||
::
|
::
|
||||||
|
|
||||||
template <class AccessTag, class TraversalTag>
|
template <class AccessTag, class TraversalTag>
|
||||||
struct iterator_tag : appropriate old category
|
struct iterator_tag : /* appropriate old category */
|
||||||
{
|
{
|
||||||
typedef AccessTag access;
|
typedef AccessTag access;
|
||||||
typedef TraversalTag traversal;
|
typedef TraversalTag traversal;
|
||||||
@@ -530,7 +530,7 @@ Addition to [lib.iterator.synopsis]
|
|||||||
template <class Iterator> struct traversal_category;
|
template <class Iterator> struct traversal_category;
|
||||||
|
|
||||||
template <class AccessTag, class TraversalTag>
|
template <class AccessTag, class TraversalTag>
|
||||||
struct iterator_tag : appropriate old category {
|
struct iterator_tag : /* appropriate old category */ {
|
||||||
typedef AccessTag access;
|
typedef AccessTag access;
|
||||||
typedef TraversalTag traversal;
|
typedef TraversalTag traversal;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user