mirror of
https://github.com/boostorg/iterator.git
synced 2025-05-11 13:33:56 +00:00
Iterator: merge several changes from trunk.
- Update iterator_facade test for #1019 (header change already merged). - Category of each iterator is reduced to a known category before we try to find a minimum. Fixes #1517. - `function_input_iterator` from Dean Michael Berris. Fixes #2893 - Fix typo in `boost/iterator.hpp`. Fixes #3434. - Always include `add_reference` header in iterator adaptor header. Did not merge changes for #1427. [SVN r70709]
This commit is contained in:
parent
d45b57c33c
commit
1ca1caddff
142
doc/function_input_iterator.html
Normal file
142
doc/function_input_iterator.html
Normal file
@ -0,0 +1,142 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
|
||||
<title></title>
|
||||
<meta name="author" content="Dean Michael Berris" />
|
||||
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="document">
|
||||
|
||||
<table class="docinfo" frame="void" rules="none">
|
||||
<col class="docinfo-name" />
|
||||
<col class="docinfo-content" />
|
||||
<tbody valign="top">
|
||||
<tr><th class="docinfo-name">Author:</th>
|
||||
<td><a class="first reference external" href="mailto:mikhailberis@gmail.com">Dean Michael Berris</a></td></tr>
|
||||
<tr class="field"><th class="docinfo-name">License:</th><td class="field-body">Distributed under the Boost Software License, Version 1.0
|
||||
(See accompanying file LICENSE_1_0.txt or copy at <a class="reference external" href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="section" id="function-input-iterator">
|
||||
<h1>Function Input Iterator</h1>
|
||||
<p>The Function Input Iterator allows for creating iterators that encapsulate
|
||||
a nullary function object and a state object which tracks the number of times
|
||||
the iterator has been incremented. A Function Input Iterator models the
|
||||
<a class="reference external" href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a> concept and is useful for creating bounded input iterators.</p>
|
||||
<p>Like the Generator Iterator, the Function Input Iterator takes a function
|
||||
that models the <a class="reference external" href="http://www.sgi.com/tech/stl/Generator.html">Generator</a> concept (which is basically a nullary or 0-arity
|
||||
function object). Each increment of the function Function Input Iterator
|
||||
invokes the generator function and stores the value in the iterator. When
|
||||
the iterator is dereferenced the stored value is returned.</p>
|
||||
<p>The Function Input Iterator encapsulates a state object which models the
|
||||
<a class="reference internal" href="#incrementable-concept">Incrementable Concept</a> and the <a class="reference external" href="http://www.sgi.com/tech/stl/EqualityComparable.html">EqualityComparable</a> Concept. These concepts are
|
||||
described below as:</p>
|
||||
<div class="section" id="incrementable-concept">
|
||||
<h2>Incrementable Concept</h2>
|
||||
<p>A type models the Incrementable Concept when it supports the pre- and post-
|
||||
increment operators. For a given object <tt class="docutils literal"><span class="pre">i</span></tt> with type <tt class="docutils literal"><span class="pre">I</span></tt>, the following
|
||||
constructs should be valid:</p>
|
||||
<table border="1" class="docutils">
|
||||
<colgroup>
|
||||
<col width="24%" />
|
||||
<col width="46%" />
|
||||
<col width="30%" />
|
||||
</colgroup>
|
||||
<tbody valign="top">
|
||||
<tr><td colspan="3">Construct Description Return Type</td>
|
||||
</tr>
|
||||
<tr><td>i++</td>
|
||||
<td>Post-increment i.</td>
|
||||
<td>I</td>
|
||||
</tr>
|
||||
<tr><td>++i</td>
|
||||
<td>Pre-increment i.</td>
|
||||
<td>I&</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>NOTE: An Incrementable type should also be <a class="reference external" href="http://www.sgi.com/tech/stl/DefaultConstructible.html">DefaultConstructible</a>.</p>
|
||||
</div>
|
||||
<div class="section" id="synopsis">
|
||||
<h2>Synopsis</h2>
|
||||
<pre class="literal-block">
|
||||
namespace {
|
||||
template <class Function, class State>
|
||||
class function_input_iterator;
|
||||
|
||||
template <class Function, class State>
|
||||
typename function_input_iterator<Function, State>
|
||||
make_function_input_iterator(Function & f);
|
||||
|
||||
struct infinite;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" id="function-input-iterator-class">
|
||||
<h2>Function Input Iterator Class</h2>
|
||||
<p>The class Function Input Iterator class takes two template parameters
|
||||
<tt class="docutils literal"><span class="pre">Function</span></tt> and <tt class="docutils literal"><span class="pre">State</span></tt>. These two template parameters tell the
|
||||
Function Input Iterator the type of the function to encapsulate and
|
||||
the type of the internal state value to hold.</p>
|
||||
<p>The <tt class="docutils literal"><span class="pre">State</span></tt> parameter is important in cases where you want to
|
||||
control the type of the counter which determines whether two iterators
|
||||
are at the same state. This allows for creating a pair of iterators which
|
||||
bound the range of the invocations of the encapsulated functions.</p>
|
||||
</div>
|
||||
<div class="section" id="examples">
|
||||
<h2>Examples</h2>
|
||||
<p>The following example shows how we use the function input iterator class
|
||||
in cases where we want to create bounded (lazy) generated ranges.</p>
|
||||
<pre class="literal-block">
|
||||
struct generator {
|
||||
typedef int result_type;
|
||||
generator() { srand(time(0)); }
|
||||
result_type operator() () const {
|
||||
return rand();
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
generator f;
|
||||
copy(
|
||||
make_function_input_iterator(f, 0),
|
||||
make_function_input_iterator(f, 10),
|
||||
ostream_iterator<int>(cout, " ")
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
<p>Here we can see that we've bounded the number of invocations using an <tt class="docutils literal"><span class="pre">int</span></tt>
|
||||
that counts from <tt class="docutils literal"><span class="pre">0</span></tt> to <tt class="docutils literal"><span class="pre">10</span></tt>. Say we want to create an endless stream
|
||||
of random numbers and encapsulate that in a pair of integers, we can do
|
||||
it with the <tt class="docutils literal"><span class="pre">boost::infinite</span></tt> helper class.</p>
|
||||
<pre class="literal-block">
|
||||
copy(
|
||||
make_function_input_iterator(f,infinite()),
|
||||
make_function_input_iterator(f,infinite()),
|
||||
ostream_iterator<int>(count, " ")
|
||||
);
|
||||
</pre>
|
||||
<p>Above, instead of creating a huge vector we rely on the STL copy algorithm
|
||||
to traverse the function input iterator and call the function object f
|
||||
as it increments the iterator. The special property of <tt class="docutils literal"><span class="pre">boost::infinite</span></tt>
|
||||
is that equating two instances always yield false -- and that incrementing
|
||||
an instance of <tt class="docutils literal"><span class="pre">boost::infinite</span></tt> doesn't do anything. This is an efficient
|
||||
way of stating that the iterator range provided by two iterators with an
|
||||
encapsulated infinite state will definitely be infinite.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<hr class="footer" />
|
||||
<a class="reference external" href="function_input_iterator.rst">View document source</a>.
|
||||
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
126
doc/function_input_iterator.rst
Normal file
126
doc/function_input_iterator.rst
Normal file
@ -0,0 +1,126 @@
|
||||
:Author:
|
||||
`Dean Michael Berris <mailto:mikhailberis@gmail.com>`_
|
||||
|
||||
:License:
|
||||
Distributed under the Boost Software License, Version 1.0
|
||||
(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
Function Input Iterator
|
||||
=======================
|
||||
|
||||
The Function Input Iterator allows for creating iterators that encapsulate
|
||||
a nullary function object and a state object which tracks the number of times
|
||||
the iterator has been incremented. A Function Input Iterator models the
|
||||
`InputIterator`_ concept and is useful for creating bounded input iterators.
|
||||
|
||||
.. _InputIterator: http://www.sgi.com/tech/stl/InputIterator.html
|
||||
|
||||
Like the Generator Iterator, the Function Input Iterator takes a function
|
||||
that models the Generator_ concept (which is basically a nullary or 0-arity
|
||||
function object). Each increment of the function Function Input Iterator
|
||||
invokes the generator function and stores the value in the iterator. When
|
||||
the iterator is dereferenced the stored value is returned.
|
||||
|
||||
.. _Generator: http://www.sgi.com/tech/stl/Generator.html
|
||||
|
||||
The Function Input Iterator encapsulates a state object which models the
|
||||
`Incrementable Concept`_ and the EqualityComparable_ Concept. These concepts are
|
||||
described below as:
|
||||
|
||||
.. _EqualityComparable: http://www.sgi.com/tech/stl/EqualityComparable.html
|
||||
|
||||
Incrementable Concept
|
||||
---------------------
|
||||
|
||||
A type models the Incrementable Concept when it supports the pre- and post-
|
||||
increment operators. For a given object ``i`` with type ``I``, the following
|
||||
constructs should be valid:
|
||||
|
||||
========= ================= ===========
|
||||
Construct Description Return Type
|
||||
-----------------------------------------
|
||||
i++ Post-increment i. I
|
||||
++i Pre-increment i. I&
|
||||
========= ================= ===========
|
||||
|
||||
NOTE: An Incrementable type should also be DefaultConstructible_.
|
||||
|
||||
.. _DefaultConstructible: http://www.sgi.com/tech/stl/DefaultConstructible.html
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
::
|
||||
|
||||
namespace {
|
||||
template <class Function, class State>
|
||||
class function_input_iterator;
|
||||
|
||||
template <class Function, class State>
|
||||
typename function_input_iterator<Function, State>
|
||||
make_function_input_iterator(Function & f);
|
||||
|
||||
struct infinite;
|
||||
}
|
||||
|
||||
Function Input Iterator Class
|
||||
-----------------------------
|
||||
|
||||
The class Function Input Iterator class takes two template parameters
|
||||
``Function`` and ``State``. These two template parameters tell the
|
||||
Function Input Iterator the type of the function to encapsulate and
|
||||
the type of the internal state value to hold.
|
||||
|
||||
The ``State`` parameter is important in cases where you want to
|
||||
control the type of the counter which determines whether two iterators
|
||||
are at the same state. This allows for creating a pair of iterators which
|
||||
bound the range of the invocations of the encapsulated functions.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
The following example shows how we use the function input iterator class
|
||||
in cases where we want to create bounded (lazy) generated ranges.
|
||||
|
||||
::
|
||||
|
||||
struct generator {
|
||||
typedef int result_type;
|
||||
generator() { srand(time(0)); }
|
||||
result_type operator() () const {
|
||||
return rand();
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
generator f;
|
||||
copy(
|
||||
make_function_input_iterator(f, 0),
|
||||
make_function_input_iterator(f, 10),
|
||||
ostream_iterator<int>(cout, " ")
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Here we can see that we've bounded the number of invocations using an ``int``
|
||||
that counts from ``0`` to ``10``. Say we want to create an endless stream
|
||||
of random numbers and encapsulate that in a pair of integers, we can do
|
||||
it with the ``boost::infinite`` helper class.
|
||||
|
||||
::
|
||||
|
||||
copy(
|
||||
make_function_input_iterator(f,infinite()),
|
||||
make_function_input_iterator(f,infinite()),
|
||||
ostream_iterator<int>(count, " ")
|
||||
);
|
||||
|
||||
Above, instead of creating a huge vector we rely on the STL copy algorithm
|
||||
to traverse the function input iterator and call the function object f
|
||||
as it increments the iterator. The special property of ``boost::infinite``
|
||||
is that equating two instances always yield false -- and that incrementing
|
||||
an instance of ``boost::infinite`` doesn't do anything. This is an efficient
|
||||
way of stating that the iterator range provided by two iterators with an
|
||||
encapsulated infinite state will definitely be infinite.
|
||||
|
||||
|
44
doc/index.html
Executable file → Normal file
44
doc/index.html
Executable file → Normal file
@ -3,7 +3,7 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
|
||||
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
|
||||
<title>The Boost.Iterator Library Boost</title>
|
||||
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
|
||||
</head>
|
||||
@ -11,9 +11,6 @@
|
||||
<div class="document" id="the-boost-iterator-library-logo">
|
||||
<h1 class="title">The Boost.Iterator Library <a class="reference external" href="../../../index.htm"><img alt="Boost" src="../../../boost.png" /></a></h1>
|
||||
|
||||
<!-- Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<!-- Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
@ -60,21 +57,21 @@ older Boost Iterator Adaptor Library.</td>
|
||||
<div class="contents topic" id="table-of-contents">
|
||||
<p class="topic-title first"><strong>Table of Contents</strong></p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference internal" href="#new-style-iterators" id="id22">New-Style Iterators</a></li>
|
||||
<li><a class="reference internal" href="#iterator-facade-and-adaptor" id="id23">Iterator Facade and Adaptor</a></li>
|
||||
<li><a class="reference internal" href="#specialized-adaptors" id="id24">Specialized Adaptors</a></li>
|
||||
<li><a class="reference internal" href="#iterator-utilities" id="id25">Iterator Utilities</a><ul>
|
||||
<li><a class="reference internal" href="#traits" id="id26">Traits</a></li>
|
||||
<li><a class="reference internal" href="#testing-and-concept-checking" id="id27">Testing and Concept Checking</a></li>
|
||||
<li><a class="reference internal" href="#new-style-iterators" id="id23">New-Style Iterators</a></li>
|
||||
<li><a class="reference internal" href="#iterator-facade-and-adaptor" id="id24">Iterator Facade and Adaptor</a></li>
|
||||
<li><a class="reference internal" href="#specialized-adaptors" id="id25">Specialized Adaptors</a></li>
|
||||
<li><a class="reference internal" href="#iterator-utilities" id="id26">Iterator Utilities</a><ul>
|
||||
<li><a class="reference internal" href="#traits" id="id27">Traits</a></li>
|
||||
<li><a class="reference internal" href="#testing-and-concept-checking" id="id28">Testing and Concept Checking</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#upgrading-from-the-old-boost-iterator-adaptor-library" id="id28">Upgrading from the old Boost Iterator Adaptor Library</a></li>
|
||||
<li><a class="reference internal" href="#history" id="id29">History</a></li>
|
||||
<li><a class="reference internal" href="#upgrading-from-the-old-boost-iterator-adaptor-library" id="id29">Upgrading from the old Boost Iterator Adaptor Library</a></li>
|
||||
<li><a class="reference internal" href="#history" id="id30">History</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<hr class="docutils" />
|
||||
<div class="section" id="new-style-iterators">
|
||||
<h1><a class="toc-backref" href="#id22">New-Style Iterators</a></h1>
|
||||
<h1><a class="toc-backref" href="#id23">New-Style Iterators</a></h1>
|
||||
<p>The iterator categories defined in C++98 are extremely limiting
|
||||
because they bind together two orthogonal concepts: traversal and
|
||||
element access. For example, because a random access iterator is
|
||||
@ -93,7 +90,7 @@ concepts, see our</p>
|
||||
<a class="reference external" href="new-iter-concepts.html">Standard Proposal For New-Style Iterators</a> (<a class="reference external" href="new-iter-concepts.pdf">PDF</a>)</blockquote>
|
||||
</div>
|
||||
<div class="section" id="iterator-facade-and-adaptor">
|
||||
<h1><a class="toc-backref" href="#id23">Iterator Facade and Adaptor</a></h1>
|
||||
<h1><a class="toc-backref" href="#id24">Iterator Facade and Adaptor</a></h1>
|
||||
<p>Writing standard-conforming iterators is tricky, but the need comes
|
||||
up often. In order to ease the implementation of new iterators,
|
||||
the Boost.Iterator library provides the <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> class template,
|
||||
@ -120,7 +117,7 @@ and accepted into the first C++ technical report; see our</p>
|
||||
<p>for more details.</p>
|
||||
</div>
|
||||
<div class="section" id="specialized-adaptors">
|
||||
<h1><a class="toc-backref" href="#id24">Specialized Adaptors</a></h1>
|
||||
<h1><a class="toc-backref" href="#id25">Specialized Adaptors</a></h1>
|
||||
<p>The iterator library supplies a useful suite of standard-conforming
|
||||
iterator templates based on the Boost <a class="reference internal" href="#iterator-facade-and-adaptor">iterator facade and adaptor</a>.</p>
|
||||
<ul class="simple">
|
||||
@ -128,6 +125,9 @@ iterator templates based on the Boost <a class="reference internal" href="#itera
|
||||
Implements a "lazy sequence"</li>
|
||||
<li><a class="reference external" href="filter_iterator.html"><tt class="docutils literal"><span class="pre">filter_iterator</span></tt></a> (<a class="reference external" href="filter_iterator.pdf">PDF</a>): an iterator over the subset of elements of some
|
||||
sequence which satisfy a given predicate</li>
|
||||
<li><a class="reference external" href="function_input_iterator.html"><tt class="docutils literal"><span class="pre">function_input_iterator</span></tt></a> (<a class="reference external" href="function_input_iterator.pdf">PDF</a>): an input iterator wrapping a generator (nullary
|
||||
function object); each time the iterator is dereferenced, the function object
|
||||
is called to get the value to return.</li>
|
||||
<li><a class="reference external" href="function_output_iterator.html"><tt class="docutils literal"><span class="pre">function_output_iterator</span></tt></a> (<a class="reference external" href="function_output_iterator.pdf">PDF</a>): an output iterator wrapping a unary function
|
||||
object; each time an element is written into the dereferenced
|
||||
iterator, it is passed as a parameter to the function object.</li>
|
||||
@ -149,9 +149,9 @@ positions of heterogeneous underlying iterators.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="iterator-utilities">
|
||||
<h1><a class="toc-backref" href="#id25">Iterator Utilities</a></h1>
|
||||
<h1><a class="toc-backref" href="#id26">Iterator Utilities</a></h1>
|
||||
<div class="section" id="traits">
|
||||
<h2><a class="toc-backref" href="#id26">Traits</a></h2>
|
||||
<h2><a class="toc-backref" href="#id27">Traits</a></h2>
|
||||
<ul class="simple">
|
||||
<li><a class="reference external" href="pointee.html"><tt class="docutils literal"><span class="pre">pointee.hpp</span></tt></a> (<a class="reference external" href="pointee.pdf">PDF</a>): Provides the capability to deduce the referent types
|
||||
of pointers, smart pointers and iterators in generic code. Used
|
||||
@ -165,7 +165,7 @@ testing iterator interoperability -->
|
||||
<!-- comment! __ interoperable.pdf -->
|
||||
</div>
|
||||
<div class="section" id="testing-and-concept-checking">
|
||||
<h2><a class="toc-backref" href="#id27">Testing and Concept Checking</a></h2>
|
||||
<h2><a class="toc-backref" href="#id28">Testing and Concept Checking</a></h2>
|
||||
<ul class="simple">
|
||||
<li><a class="reference external" href="iterator_concepts.html"><tt class="docutils literal"><span class="pre">iterator_concepts.hpp</span></tt></a> (<a class="reference external" href="iterator_concepts.pdf">PDF</a>): Concept checking classes for the new iterator concepts.</li>
|
||||
<li><a class="reference external" href="iterator_archetypes.html"><tt class="docutils literal"><span class="pre">iterator_archetypes.hpp</span></tt></a> (<a class="reference external" href="iterator_archetypes.pdf">PDF</a>): Concept archetype classes for the new iterators concepts.</li>
|
||||
@ -173,7 +173,7 @@ testing iterator interoperability -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="upgrading-from-the-old-boost-iterator-adaptor-library">
|
||||
<h1><a class="toc-backref" href="#id28">Upgrading from the old Boost Iterator Adaptor Library</a></h1>
|
||||
<h1><a class="toc-backref" href="#id29">Upgrading from the old Boost Iterator Adaptor Library</a></h1>
|
||||
<p id="upgrading">If you have been using the old Boost Iterator Adaptor library to
|
||||
implement iterators, you probably wrote a <tt class="docutils literal"><span class="pre">Policies</span></tt> class which
|
||||
captures the core operations of your iterator. In the new library
|
||||
@ -183,7 +183,7 @@ you probably wrote a <a class="reference external" href="http://www.boost.org/mo
|
||||
<tt class="docutils literal"><span class="pre">iterator_adaptor</span></tt> specialization you needed; in the new library
|
||||
design you don't need a type generator (though may want to keep it
|
||||
around as a compatibility aid for older code) because, due to the
|
||||
use of the Curiously Recurring Template Pattern (CRTP) <a class="citation-reference" href="#cop95" id="id21">[Cop95]</a>,
|
||||
use of the Curiously Recurring Template Pattern (CRTP) <a class="citation-reference" href="#cop95" id="id22">[Cop95]</a>,
|
||||
you can now define the iterator class yourself and acquire
|
||||
functionality through inheritance from <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> or
|
||||
<tt class="docutils literal"><span class="pre">iterator_adaptor</span></tt>. As a result, you also get much finer control
|
||||
@ -198,7 +198,7 @@ type, <tt class="docutils literal"><span class="pre">transform_iterator</span></
|
||||
<tt class="docutils literal"><span class="pre">projection_iterator</span></tt> used to.</p>
|
||||
</div>
|
||||
<div class="section" id="history">
|
||||
<h1><a class="toc-backref" href="#id29">History</a></h1>
|
||||
<h1><a class="toc-backref" href="#id30">History</a></h1>
|
||||
<p>In 2000 Dave Abrahams was writing an iterator for a container of
|
||||
pointers, which would access the pointed-to elements when
|
||||
dereferenced. Naturally, being a library writer, he decided to
|
||||
@ -226,7 +226,7 @@ library you see today.</p>
|
||||
<table class="docutils citation" frame="void" id="cop95" rules="none">
|
||||
<colgroup><col class="label" /><col /></colgroup>
|
||||
<tbody valign="top">
|
||||
<tr><td class="label"><a class="fn-backref" href="#id21">[Cop95]</a></td><td>[Coplien, 1995] Coplien, J., Curiously Recurring Template
|
||||
<tr><td class="label"><a class="fn-backref" href="#id22">[Cop95]</a></td><td>[Coplien, 1995] Coplien, J., Curiously Recurring Template
|
||||
Patterns, C++ Report, February 1995, pp. 24-27.</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
14
doc/index.rst
Executable file → Normal file
14
doc/index.rst
Executable file → Normal file
@ -138,7 +138,11 @@ iterator templates based on the Boost `iterator facade and adaptor`_.
|
||||
* |filter|_ (PDF__): an iterator over the subset of elements of some
|
||||
sequence which satisfy a given predicate
|
||||
|
||||
* |function|_ (PDF__): an output iterator wrapping a unary function
|
||||
* |function_input|_ (PDF__): an input iterator wrapping a generator (nullary
|
||||
function object); each time the iterator is dereferenced, the function object
|
||||
is called to get the value to return.
|
||||
|
||||
* |function_output|_ (PDF__): an output iterator wrapping a unary function
|
||||
object; each time an element is written into the dereferenced
|
||||
iterator, it is passed as a parameter to the function object.
|
||||
|
||||
@ -171,8 +175,12 @@ __ counting_iterator.pdf
|
||||
.. _filter: filter_iterator.html
|
||||
__ filter_iterator.pdf
|
||||
|
||||
.. |function| replace:: ``function_output_iterator``
|
||||
.. _function: function_output_iterator.html
|
||||
.. |function_input| replace:: ``function_input_iterator``
|
||||
.. _function_input: function_input_iterator.html
|
||||
__ function_input_iterator.pdf
|
||||
|
||||
.. |function_output| replace:: ``function_output_iterator``
|
||||
.. _function_output: function_output_iterator.html
|
||||
__ function_output_iterator.pdf
|
||||
|
||||
.. |indirect| replace:: ``indirect_iterator``
|
||||
|
@ -6,6 +6,7 @@ sources = [
|
||||
'counting_iterator.rst',
|
||||
'facade-and-adaptor.rst',
|
||||
'filter_iterator.rst',
|
||||
'function_input_iterator.rst',
|
||||
'function_output_iterator.rst',
|
||||
'index.rst',
|
||||
'indirect_iterator.rst',
|
||||
|
@ -1,4 +1,4 @@
|
||||
// interator.hpp workarounds for non-conforming standard libraries ---------//
|
||||
// iterator.hpp workarounds for non-conforming standard libraries ---------//
|
||||
|
||||
// (C) Copyright Beman Dawes 2000. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
|
150
include/boost/iterator/function_input_iterator.hpp
Normal file
150
include/boost/iterator/function_input_iterator.hpp
Normal file
@ -0,0 +1,150 @@
|
||||
// Copyright 2009 (C) Dean Michael Berris <me@deanberris.com>
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BOOST_FUNCTION_INPUT_ITERATOR
|
||||
#define BOOST_FUNCTION_INPUT_ITERATOR
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/function_types/is_function_pointer.hpp>
|
||||
#include <boost/function_types/is_function_reference.hpp>
|
||||
#include <boost/function_types/result_type.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace impl {
|
||||
|
||||
template <class Function, class Input>
|
||||
class function_input_iterator
|
||||
: public iterator_facade<
|
||||
function_input_iterator<Function, Input>,
|
||||
typename Function::result_type,
|
||||
single_pass_traversal_tag,
|
||||
typename Function::result_type const &
|
||||
>
|
||||
{
|
||||
public:
|
||||
function_input_iterator() {}
|
||||
function_input_iterator(Function & f_, Input state_ = Input())
|
||||
: f(&f_), state(state_), value((*f)()) {}
|
||||
|
||||
void increment() {
|
||||
value = (*f)();
|
||||
++state;
|
||||
}
|
||||
|
||||
typename Function::result_type const &
|
||||
dereference() const {
|
||||
return value;
|
||||
}
|
||||
|
||||
bool equal(function_input_iterator const & other) const {
|
||||
return f == other.f && state == other.state;
|
||||
}
|
||||
|
||||
private:
|
||||
Function * f;
|
||||
Input state;
|
||||
typename Function::result_type value;
|
||||
};
|
||||
|
||||
template <class Function, class Input>
|
||||
class function_pointer_input_iterator
|
||||
: public iterator_facade<
|
||||
function_pointer_input_iterator<Function, Input>,
|
||||
typename function_types::result_type<Function>::type,
|
||||
single_pass_traversal_tag,
|
||||
typename function_types::result_type<Function>::type const &
|
||||
>
|
||||
{
|
||||
public:
|
||||
function_pointer_input_iterator() {}
|
||||
function_pointer_input_iterator(Function &f_, Input state_ = Input())
|
||||
: f(f_), state(state_), value((*f)())
|
||||
{}
|
||||
|
||||
void increment() {
|
||||
value = (*f)();
|
||||
++state;
|
||||
}
|
||||
|
||||
typename function_types::result_type<Function>::type const &
|
||||
dereference() const {
|
||||
return value;
|
||||
}
|
||||
|
||||
bool equal(function_pointer_input_iterator const & other) const {
|
||||
return f == other.f && state == other.state;
|
||||
}
|
||||
|
||||
private:
|
||||
Function f;
|
||||
Input state;
|
||||
typename function_types::result_type<Function>::type value;
|
||||
};
|
||||
|
||||
template <class Function, class Input>
|
||||
class function_reference_input_iterator
|
||||
: public function_pointer_input_iterator<Function*,Input>
|
||||
{
|
||||
public:
|
||||
function_reference_input_iterator(Function & f_, Input state_ = Input())
|
||||
: function_pointer_input_iterator<Function*,Input>(&f_, state_)
|
||||
{}
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
||||
template <class Function, class Input>
|
||||
class function_input_iterator
|
||||
: public mpl::if_<
|
||||
function_types::is_function_pointer<Function>,
|
||||
impl::function_pointer_input_iterator<Function,Input>,
|
||||
typename mpl::if_<
|
||||
function_types::is_function_reference<Function>,
|
||||
impl::function_reference_input_iterator<Function,Input>,
|
||||
impl::function_input_iterator<Function,Input>
|
||||
>::type
|
||||
>::type
|
||||
{
|
||||
typedef typename mpl::if_<
|
||||
function_types::is_function_pointer<Function>,
|
||||
impl::function_pointer_input_iterator<Function,Input>,
|
||||
typename mpl::if_<
|
||||
function_types::is_function_reference<Function>,
|
||||
impl::function_reference_input_iterator<Function,Input>,
|
||||
impl::function_input_iterator<Function,Input>
|
||||
>::type
|
||||
>::type base_type;
|
||||
public:
|
||||
function_input_iterator(Function & f, Input i)
|
||||
: base_type(f, i) {}
|
||||
};
|
||||
|
||||
template <class Function, class Input>
|
||||
inline function_input_iterator<Function, Input>
|
||||
make_function_input_iterator(Function & f, Input state) {
|
||||
typedef function_input_iterator<Function, Input> result_t;
|
||||
return result_t(f, state);
|
||||
}
|
||||
|
||||
template <class Function, class Input>
|
||||
inline function_input_iterator<Function*, Input>
|
||||
make_function_input_iterator(Function * f, Input state) {
|
||||
typedef function_input_iterator<Function*, Input> result_t;
|
||||
return result_t(f, state);
|
||||
}
|
||||
|
||||
struct infinite {
|
||||
infinite & operator++() { return *this; }
|
||||
infinite & operator++(int) { return *this; }
|
||||
bool operator==(infinite &) const { return false; };
|
||||
bool operator==(infinite const &) const { return false; };
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -24,15 +24,9 @@
|
||||
|
||||
#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
||||
# include <boost/type_traits/remove_reference.hpp>
|
||||
|
||||
# if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x610))
|
||||
# include <boost/type_traits/add_reference.hpp>
|
||||
# endif
|
||||
|
||||
#else
|
||||
# include <boost/type_traits/add_reference.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/type_traits/add_reference.hpp>
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
|
2
include/boost/iterator/zip_iterator.hpp
Executable file → Normal file
2
include/boost/iterator/zip_iterator.hpp
Executable file → Normal file
@ -357,7 +357,7 @@ namespace boost {
|
||||
{
|
||||
typedef typename tuple_impl_specific::tuple_meta_transform<
|
||||
IteratorTuple
|
||||
, iterator_traversal<>
|
||||
, pure_traversal_tag<iterator_traversal<> >
|
||||
>::type tuple_of_traversal_tags;
|
||||
|
||||
typedef typename tuple_impl_specific::tuple_meta_accumulate<
|
||||
|
@ -43,5 +43,6 @@ test-suite iterator
|
||||
[ run iterator_traits_test.cpp ]
|
||||
[ run permutation_iterator_test.cpp : : : # <stlport-iostream>on
|
||||
]
|
||||
[ run function_input_iterator_test.cpp ]
|
||||
|
||||
;
|
||||
|
70
test/function_input_iterator_test.cpp
Normal file
70
test/function_input_iterator_test.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
// Copyright 2010 (c) Dean Michael Berris
|
||||
// Distributed under the Boost Software License Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/iterator/function_input_iterator.hpp>
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
struct ones {
|
||||
typedef int result_type;
|
||||
result_type operator() () {
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
int ones_function () {
|
||||
return 1;
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
// test the iterator with function objects
|
||||
ones ones_generator;
|
||||
vector<int> values(10);
|
||||
generate(values.begin(), values.end(), ones());
|
||||
|
||||
vector<int> generated;
|
||||
copy(
|
||||
boost::make_function_input_iterator(ones_generator, 0),
|
||||
boost::make_function_input_iterator(ones_generator, 10),
|
||||
back_inserter(generated)
|
||||
);
|
||||
|
||||
assert(values.size() == generated.size());
|
||||
assert(equal(values.begin(), values.end(), generated.begin()));
|
||||
cout << "function iterator test with function objects successful." << endl;
|
||||
|
||||
// test the iterator with normal functions
|
||||
vector<int>().swap(generated);
|
||||
copy(
|
||||
boost::make_function_input_iterator(&ones_function, 0),
|
||||
boost::make_function_input_iterator(&ones_function, 10),
|
||||
back_inserter(generated)
|
||||
);
|
||||
|
||||
assert(values.size() == generated.size());
|
||||
assert(equal(values.begin(), values.end(), generated.begin()));
|
||||
cout << "function iterator test with pointer to function successful." << endl;
|
||||
|
||||
// test the iterator with a reference to a function
|
||||
vector<int>().swap(generated);
|
||||
copy(
|
||||
boost::make_function_input_iterator(ones_function, 0),
|
||||
boost::make_function_input_iterator(ones_function, 10),
|
||||
back_inserter(generated)
|
||||
);
|
||||
|
||||
assert(values.size() == generated.size());
|
||||
assert(equal(values.begin(), values.end(), generated.begin()));
|
||||
cout << "function iterator test with reference to function successful." << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
6
test/iterator_facade.cpp
Executable file → Normal file
6
test/iterator_facade.cpp
Executable file → Normal file
@ -87,6 +87,10 @@ struct input_iter
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class U>
|
||||
void same_type(U const&)
|
||||
{ BOOST_MPL_ASSERT((boost::is_same<T,U>)); }
|
||||
|
||||
int main()
|
||||
{
|
||||
int state = 0;
|
||||
@ -101,6 +105,8 @@ int main()
|
||||
input_iter p;
|
||||
(*p).mutator();
|
||||
p->mutator();
|
||||
|
||||
same_type<input_iter::pointer>(p.operator->());
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
24
test/zip_iterator_test.cpp
Executable file → Normal file
24
test/zip_iterator_test.cpp
Executable file → Normal file
@ -46,6 +46,7 @@
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
@ -60,6 +61,27 @@ struct pure_traversal
|
||||
typename boost::iterator_traversal<It>::type
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
/// Tests for https://svn.boost.org/trac/boost/ticket/1517
|
||||
int to_value(int const &v)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
void category_test()
|
||||
{
|
||||
std::list<int> rng1;
|
||||
std::string rng2;
|
||||
|
||||
boost::make_zip_iterator(
|
||||
boost::make_tuple(
|
||||
boost::make_transform_iterator(rng1.begin(), &to_value), // BidirectionalInput
|
||||
rng2.begin() // RandomAccess
|
||||
)
|
||||
);
|
||||
}
|
||||
///
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@ -70,6 +92,8 @@ struct pure_traversal
|
||||
int main( void )
|
||||
{
|
||||
|
||||
category_test();
|
||||
|
||||
std::cout << "\n"
|
||||
<< "***********************************************\n"
|
||||
<< "* *\n"
|
||||
|
Loading…
x
Reference in New Issue
Block a user