Compare commits

..

5 Commits

Author SHA1 Message Date
a9b594c925 v2, v3, integration branch
[SVN r62649]
2010-06-09 11:34:33 +00:00
251b9f8057 Fixed #3434
[SVN r62626]
2010-06-09 01:13:28 +00:00
2786268510 Applied patches from #1427; fixes #1427
[SVN r62625]
2010-06-09 01:08:45 +00:00
6bb82230b9 Added function_input_iterator from Dean Michael Berris; fixes #2893
[SVN r62615]
2010-06-09 00:09:56 +00:00
c07f55ff65 Removed unneeded #include; fixes #1533
[SVN r62593]
2010-06-08 19:10:16 +00:00
9 changed files with 404 additions and 47 deletions

View 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&#64;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&amp;</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 &lt;class Function, class State&gt;
class function_input_iterator;
template &lt;class Function, class State&gt;
typename function_input_iterator&lt;Function, State&gt;
make_function_input_iterator(Function &amp; 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&lt;int&gt;(cout, &quot; &quot;)
);
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&lt;int&gt;(count, &quot; &quot;)
);
</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>

View 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.

View File

@ -3,7 +3,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <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> <title>The Boost.Iterator Library Boost</title>
<link rel="stylesheet" href="../../../rst.css" type="text/css" /> <link rel="stylesheet" href="../../../rst.css" type="text/css" />
</head> </head>
@ -11,9 +11,6 @@
<div class="document" id="the-boost-iterator-library-logo"> <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> <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 --> <!-- Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying --> <!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) --> <!-- 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"> <div class="contents topic" id="table-of-contents">
<p class="topic-title first"><strong>Table of Contents</strong></p> <p class="topic-title first"><strong>Table of Contents</strong></p>
<ul class="simple"> <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="#new-style-iterators" id="id23">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="#iterator-facade-and-adaptor" id="id24">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="#specialized-adaptors" id="id25">Specialized Adaptors</a></li>
<li><a class="reference internal" href="#iterator-utilities" id="id25">Iterator Utilities</a><ul> <li><a class="reference internal" href="#iterator-utilities" id="id26">Iterator Utilities</a><ul>
<li><a class="reference internal" href="#traits" id="id26">Traits</a></li> <li><a class="reference internal" href="#traits" id="id27">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="#testing-and-concept-checking" id="id28">Testing and Concept Checking</a></li>
</ul> </ul>
</li> </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="#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="id29">History</a></li> <li><a class="reference internal" href="#history" id="id30">History</a></li>
</ul> </ul>
</div> </div>
<hr class="docutils" /> <hr class="docutils" />
<div class="section" id="new-style-iterators"> <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 <p>The iterator categories defined in C++98 are extremely limiting
because they bind together two orthogonal concepts: traversal and because they bind together two orthogonal concepts: traversal and
element access. For example, because a random access iterator is 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> <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>
<div class="section" id="iterator-facade-and-adaptor"> <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 <p>Writing standard-conforming iterators is tricky, but the need comes
up often. In order to ease the implementation of new iterators, 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, 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> <p>for more details.</p>
</div> </div>
<div class="section" id="specialized-adaptors"> <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 <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> iterator templates based on the Boost <a class="reference internal" href="#iterator-facade-and-adaptor">iterator facade and adaptor</a>.</p>
<ul class="simple"> <ul class="simple">
@ -128,6 +125,9 @@ iterator templates based on the Boost <a class="reference internal" href="#itera
Implements a &quot;lazy sequence&quot;</li> Implements a &quot;lazy sequence&quot;</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 <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> 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 <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 object; each time an element is written into the dereferenced
iterator, it is passed as a parameter to the function object.</li> iterator, it is passed as a parameter to the function object.</li>
@ -149,9 +149,9 @@ positions of heterogeneous underlying iterators.</li>
</ul> </ul>
</div> </div>
<div class="section" id="iterator-utilities"> <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"> <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"> <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 <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 of pointers, smart pointers and iterators in generic code. Used
@ -165,7 +165,7 @@ testing iterator interoperability -->
<!-- comment! __ interoperable.pdf --> <!-- comment! __ interoperable.pdf -->
</div> </div>
<div class="section" id="testing-and-concept-checking"> <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"> <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_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> <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> </div>
<div class="section" id="upgrading-from-the-old-boost-iterator-adaptor-library"> <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 <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 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 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 <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 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 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 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 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 <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> <tt class="docutils literal"><span class="pre">projection_iterator</span></tt> used to.</p>
</div> </div>
<div class="section" id="history"> <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 <p>In 2000 Dave Abrahams was writing an iterator for a container of
pointers, which would access the pointed-to elements when pointers, which would access the pointed-to elements when
dereferenced. Naturally, being a library writer, he decided to 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"> <table class="docutils citation" frame="void" id="cop95" rules="none">
<colgroup><col class="label" /><col /></colgroup> <colgroup><col class="label" /><col /></colgroup>
<tbody valign="top"> <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> Patterns, C++ Report, February 1995, pp. 24-27.</td></tr>
</tbody> </tbody>
</table> </table>

View 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 * |filter|_ (PDF__): an iterator over the subset of elements of some
sequence which satisfy a given predicate 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 object; each time an element is written into the dereferenced
iterator, it is passed as a parameter to the function object. iterator, it is passed as a parameter to the function object.
@ -171,8 +175,12 @@ __ counting_iterator.pdf
.. _filter: filter_iterator.html .. _filter: filter_iterator.html
__ filter_iterator.pdf __ filter_iterator.pdf
.. |function| replace:: ``function_output_iterator`` .. |function_input| replace:: ``function_input_iterator``
.. _function: function_output_iterator.html .. _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 __ function_output_iterator.pdf
.. |indirect| replace:: ``indirect_iterator`` .. |indirect| replace:: ``indirect_iterator``

View File

@ -6,6 +6,7 @@ sources = [
'counting_iterator.rst', 'counting_iterator.rst',
'facade-and-adaptor.rst', 'facade-and-adaptor.rst',
'filter_iterator.rst', 'filter_iterator.rst',
'function_input_iterator.rst',
'function_output_iterator.rst', 'function_output_iterator.rst',
'index.rst', 'index.rst',
'indirect_iterator.rst', 'indirect_iterator.rst',

View File

@ -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 // (C) Copyright Beman Dawes 2000. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file // Software License, Version 1.0. (See accompanying file

View File

@ -0,0 +1,64 @@
// 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/iterator/iterator_facade.hpp>
namespace boost {
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>
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

View File

@ -7,7 +7,6 @@
#ifndef BOOST_TRANSFORM_ITERATOR_23022003THW_HPP #ifndef BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
#define BOOST_TRANSFORM_ITERATOR_23022003THW_HPP #define BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
#include <boost/function.hpp>
#include <boost/iterator.hpp> #include <boost/iterator.hpp>
#include <boost/iterator/detail/enable_if.hpp> #include <boost/iterator/detail/enable_if.hpp>
#include <boost/iterator/iterator_adaptor.hpp> #include <boost/iterator/iterator_adaptor.hpp>
@ -21,6 +20,8 @@
#include <boost/type_traits/is_reference.hpp> #include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/remove_const.hpp> #include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp> #include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/result_of.hpp>
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310)) #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
# include <boost/type_traits/is_base_and_derived.hpp> # include <boost/type_traits/is_base_and_derived.hpp>
@ -36,33 +37,18 @@ namespace boost
namespace detail namespace detail
{ {
template <class UnaryFunc>
struct function_object_result
{
typedef typename UnaryFunc::result_type type;
};
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class Return, class Argument>
struct function_object_result<Return(*)(Argument)>
{
typedef Return type;
};
#endif
// Compute the iterator_adaptor instantiation to be used for transform_iterator // Compute the iterator_adaptor instantiation to be used for transform_iterator
template <class UnaryFunc, class Iterator, class Reference, class Value> template <class UnaryFunc, class Iterator, class Reference, class Value>
struct transform_iterator_base struct transform_iterator_base
{ {
private: private:
typedef typename std::iterator_traits<Iterator>::reference Arg1;
// By default, dereferencing the iterator yields the same as // By default, dereferencing the iterator yields the same as
// the function. Do we need to adjust the way // the function.
// function_object_result is computed for the standard
// proposal (e.g. using Doug's result_of)?
typedef typename ia_dflt_help< typedef typename ia_dflt_help<
Reference Reference
, function_object_result<UnaryFunc> , result_of<UnaryFunc(typename std::iterator_traits<Iterator>::value_type)>
>::type reference; >::type reference;
// To get the default for Value: remove any reference on the // To get the default for Value: remove any reference on the
@ -114,7 +100,7 @@ namespace boost
#endif #endif
} }
template< template <
class OtherUnaryFunction class OtherUnaryFunction
, class OtherIterator , class OtherIterator
, class OtherReference , class OtherReference

View File

@ -102,6 +102,16 @@ int mult_2(int arg)
return arg*2; return arg*2;
} }
struct polymorphic_mult_functor
{
//Implement result_of protocol
template <class FArgs> struct result;
template <class F, class T> struct result<F(T)> {typedef T type;};
template <class T>
typename result<polymorphic_mult_functor(T)>::type
operator()(const T& _arg) const {return _arg*2;}
};
int int
main() main()
@ -244,5 +254,25 @@ main()
); );
} }
// Test transform_iterator with polymorphic object function
{
int x[N], y[N];
for (int k = 0; k < N; ++k)
x[k] = k;
std::copy(x, x + N, y);
for (int k2 = 0; k2 < N; ++k2)
x[k2] = x[k2] * 2;
boost::input_iterator_test(
boost::make_transform_iterator(y, polymorphic_mult_functor()), x[0], x[1]);
boost::input_iterator_test(
boost::make_transform_iterator(&y[0], polymorphic_mult_functor()), x[0], x[1]);
boost::random_access_readable_iterator_test(
boost::make_transform_iterator(y, polymorphic_mult_functor()), N, x);
}
return boost::report_errors(); return boost::report_errors();
} }