mirror of
https://github.com/boostorg/utility.git
synced 2025-05-08 18:34:02 +00:00
Obsoleted old iterator adaptor docs
[SVN r22101]
This commit is contained in:
parent
9a07bc0d9b
commit
7b472a05ee
@ -1,325 +0,0 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
<title>Counting Iterator Adaptor Documentation</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)"
|
||||
align="center" width="277" height="86">
|
||||
|
||||
<h1>Counting Iterator Adaptor</h1>
|
||||
|
||||
Defined in header
|
||||
<a href="../../boost/counting_iterator.hpp">boost/counting_iterator.hpp</a>
|
||||
|
||||
<p>
|
||||
How would you fill up a vector with the numbers zero
|
||||
through one hundred using <a
|
||||
href="http://www.sgi.com/tech/stl/copy.html"><tt>std::copy()</tt></a>? The
|
||||
only iterator operation missing from builtin integer types is an
|
||||
<tt>operator*()</tt> that returns the current
|
||||
value of the integer. The counting iterator adaptor adds this crucial piece of
|
||||
functionality to whatever type it wraps. One can use the
|
||||
counting iterator adaptor not only with integer types, but with any
|
||||
type that is <tt>Incrementable</tt> (see type requirements <a href="#requirements">below</a>). The
|
||||
following <b>pseudo-code</b> shows the general idea of how the
|
||||
counting iterator is implemented.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
// inside a hypothetical counting_iterator class...
|
||||
typedef Incrementable value_type;
|
||||
value_type counting_iterator::operator*() const {
|
||||
return this->base; // no dereference!
|
||||
}
|
||||
</pre>
|
||||
|
||||
All of the other operators of the counting iterator behave in the same
|
||||
fashion as the <tt>Incrementable</tt> base type.
|
||||
|
||||
<h2>Synopsis</h2>
|
||||
|
||||
<pre>
|
||||
namespace boost {
|
||||
template <class Incrementable>
|
||||
struct <a href="#counting_iterator_traits">counting_iterator_traits</a>;
|
||||
|
||||
template <class Incrementable>
|
||||
struct <a href="#counting_iterator_generator">counting_iterator_generator</a>;
|
||||
|
||||
template <class Incrementable>
|
||||
typename counting_iterator_generator<Incrementable>::type
|
||||
<a href="#make_counting_iterator">make_counting_iterator</a>(Incrementable x);
|
||||
}
|
||||
</pre>
|
||||
|
||||
<hr>
|
||||
|
||||
<h2><a name="counting_iterator_generator">The Counting Iterator Type
|
||||
Generator</a></h2>
|
||||
|
||||
The class template <tt>counting_iterator_generator<Incrementable></tt> is a <a href="../../more/generic_programming.html#type_generator">type generator</a> for counting iterators.
|
||||
|
||||
<pre>
|
||||
template <class Incrementable>
|
||||
class counting_iterator_generator
|
||||
{
|
||||
public:
|
||||
typedef <a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...> type;
|
||||
};
|
||||
</pre>
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
In this example we use the counting iterator generator to create a
|
||||
counting iterator, and count from zero to four.
|
||||
|
||||
<pre>
|
||||
#include <boost/config.hpp>
|
||||
#include <iostream>
|
||||
#include <boost/counting_iterator.hpp>
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
// Example of using counting_iterator_generator
|
||||
std::cout << "counting from 0 to 4:" << std::endl;
|
||||
boost::counting_iterator_generator<int>::type first(0), last(4);
|
||||
std::copy(first, last, std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
|
||||
// to be continued...
|
||||
</pre>
|
||||
The output from this part is:
|
||||
<pre>
|
||||
counting from 0 to 4:
|
||||
0 1 2 3
|
||||
</pre>
|
||||
|
||||
<h3>Template Parameters</h3>
|
||||
|
||||
<Table border>
|
||||
<TR>
|
||||
<TH>Parameter</TH><TH>Description</TH>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>Incrementable</tt></TD>
|
||||
<TD>The type being wrapped by the adaptor.</TD>
|
||||
</TR>
|
||||
|
||||
</Table>
|
||||
|
||||
<h3>Model of</h3>
|
||||
|
||||
If the <tt>Incrementable</tt> type has all of the functionality of a
|
||||
<a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
|
||||
Access Iterator</a> except the <tt>operator*()</tt>, then the counting
|
||||
iterator will be a model of <a
|
||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
|
||||
Access Iterator</a>. If the <tt>Incrementable</tt> type has less
|
||||
functionality, then the counting iterator will have correspondingly
|
||||
less functionality.
|
||||
|
||||
<h3><a name="requirements">Type Requirements</a></h3>
|
||||
|
||||
The <tt>Incrementable</tt> type must be <a
|
||||
href="http://www.sgi.com/tech/stl/DefaultConstructible.html">Default
|
||||
Constructible</a>, <a href="./CopyConstructible.html">Copy
|
||||
Constructible</a>, and <a href="./Assignable.html">Assignable</a>.
|
||||
Also, the <tt>Incrementable</tt> type must provide access to an
|
||||
associated <tt>difference_type</tt> and <tt>iterator_category</tt>
|
||||
through the <a
|
||||
href="#counting_iterator_traits"><tt>counting_iterator_traits</tt></a>
|
||||
class.
|
||||
|
||||
<p>
|
||||
Furthermore, if you wish to create a counting iterator that is a <a
|
||||
href="http://www.sgi.com/tech/stl/ForwardIterator.html"> Forward
|
||||
Iterator</a>, then the following expressions must be valid:
|
||||
<pre>
|
||||
Incrementable i, j;
|
||||
++i // pre-increment
|
||||
i == j // operator equal
|
||||
</pre>
|
||||
If you wish to create a counting iterator that is a <a
|
||||
href="http://www.sgi.com/tech/stl/BidirectionalIterator.html">
|
||||
Bidirectional Iterator</a>, then pre-decrement is also required:
|
||||
<pre>
|
||||
--i
|
||||
</pre>
|
||||
If you wish to create a counting iterator that is a <a
|
||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html"> Random
|
||||
Access Iterator</a>, then these additional expressions are also required:
|
||||
<pre>
|
||||
<a href="#counting_iterator_traits">counting_iterator_traits</a><Incrementable>::difference_type n;
|
||||
i += n
|
||||
n = i - j
|
||||
i < j
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
<h3>Members</h3>
|
||||
|
||||
The counting iterator type implements the member functions and
|
||||
operators required of the <a
|
||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
|
||||
Access Iterator</a> concept. In addition it has the following
|
||||
constructor:
|
||||
|
||||
<pre>
|
||||
counting_iterator_generator::type(const Incrementable& i)
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
<hr>
|
||||
<p>
|
||||
|
||||
|
||||
<h2><a name="make_counting_iterator">The Counting Iterator Object Generator</a></h2>
|
||||
|
||||
<pre>
|
||||
template <class Incrementable>
|
||||
typename counting_iterator_generator<Incrementable>::type
|
||||
make_counting_iterator(Incrementable base);
|
||||
</pre>
|
||||
|
||||
An <a href="../../more/generic_programming.html#object_generator">object
|
||||
generator</a> function that provides a convenient way to create counting
|
||||
iterators.<p>
|
||||
|
||||
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
In this example we count from negative five to positive five, this
|
||||
time using the <tt>make_counting_iterator()</tt> function to save some
|
||||
typing.
|
||||
|
||||
<pre>
|
||||
// continuing from previous example...
|
||||
|
||||
std::cout << "counting from -5 to 4:" << std::endl;
|
||||
std::copy(boost::make_counting_iterator(-5),
|
||||
boost::make_counting_iterator(5),
|
||||
std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
|
||||
// to be continued...
|
||||
</pre>
|
||||
The output from this part is:
|
||||
<pre>
|
||||
counting from -5 to 4:
|
||||
-5 -4 -3 -2 -1 0 1 2 3 4
|
||||
</pre>
|
||||
|
||||
In the next example we create an array of numbers, and then create a
|
||||
second array of pointers, where each pointer is the address of a
|
||||
number in the first array. The counting iterator makes it easy to do
|
||||
this since dereferencing a counting iterator that is wrapping an
|
||||
iterator over the array of numbers just returns a pointer to the
|
||||
current location in the array. We then use the <a
|
||||
href="./indirect_iterator.htm">indirect iterator adaptor</a> to print
|
||||
out the number in the array by accessing the numbers through the array
|
||||
of pointers.
|
||||
|
||||
<pre>
|
||||
// continuing from previous example...
|
||||
|
||||
const int N = 7;
|
||||
std::vector<int> numbers;
|
||||
// Fill "numbers" array with [0,N)
|
||||
std::copy(boost::make_counting_iterator(0), boost::make_counting_iterator(N),
|
||||
std::back_inserter(numbers));
|
||||
|
||||
std::vector<std::vector<int>::iterator> pointers;
|
||||
|
||||
// Use counting iterator to fill in the array of pointers.
|
||||
std::copy(boost::make_counting_iterator(numbers.begin()),
|
||||
boost::make_counting_iterator(numbers.end()),
|
||||
std::back_inserter(pointers));
|
||||
|
||||
// Use indirect iterator to print out numbers by accessing
|
||||
// them through the array of pointers.
|
||||
std::cout << "indirectly printing out the numbers from 0 to "
|
||||
<< N << std::endl;
|
||||
std::copy(boost::make_indirect_iterator(pointers.begin()),
|
||||
boost::make_indirect_iterator(pointers.end()),
|
||||
std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
</pre>
|
||||
The output is:
|
||||
<pre>
|
||||
indirectly printing out the numbers from 0 to 7
|
||||
0 1 2 3 4 5 6
|
||||
</pre>
|
||||
|
||||
<hr>
|
||||
|
||||
<h2><a name="counting_iterator_traits">Counting Iterator Traits</a></h2>
|
||||
|
||||
The counting iterator adaptor needs to determine the appropriate
|
||||
<tt>difference_type</tt> and <tt>iterator_category</tt> to use based on the
|
||||
<tt>Incrementable</tt> type supplied by the user. The
|
||||
<tt>counting_iterator_traits</tt> class provides these types. If the
|
||||
<tt>Incrementable</tt> type is an integral type or an iterator, these types
|
||||
will be correctly deduced by the <tt>counting_iterator_traits</tt> provided by
|
||||
the library. Otherwise, the user must specialize
|
||||
<tt>counting_iterator_traits</tt> for her type or add nested typedefs to
|
||||
her type to fulfill the needs of
|
||||
<a href="http://www.sgi.com/tech/stl/iterator_traits.html">
|
||||
<tt>std::iterator_traits</tt></a>.
|
||||
|
||||
<p>The following pseudocode describes how the <tt>counting_iterator_traits</tt> are determined:
|
||||
|
||||
<pre>
|
||||
template <class Incrementable>
|
||||
struct counting_iterator_traits
|
||||
{
|
||||
if (numeric_limits<Incrementable>::is_specialized) {
|
||||
if (!numeric_limits<Incrementable>::is_integer)
|
||||
COMPILE_TIME_ERROR;
|
||||
|
||||
if (!numeric_limits<Incrementable>::is_bounded
|
||||
&& numeric_limits<Incrementable>::is_signed) {
|
||||
typedef Incrementable difference_type;
|
||||
}
|
||||
else if (numeric_limits<Incrementable>::is_integral) {
|
||||
typedef <i>next-larger-signed-type-or-intmax_t</i> difference_type;
|
||||
}
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
} else {
|
||||
typedef std::iterator_traits<Incrementable>::difference_type difference_type;
|
||||
typedef std::iterator_traits<Incrementable>::iterator_category iterator_category;
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
|
||||
<p>The italicized sections above are implementation details, but it is important
|
||||
to know that the <tt>difference_type</tt> for integral types is selected so that
|
||||
it can always represent the difference between two values if such a built-in
|
||||
integer exists. On platforms with a working <tt>std::numeric_limits</tt>
|
||||
implementation, the <tt>difference_type</tt> for any variable-length signed
|
||||
integer type <tt>T</tt> is <tt>T</tt> itself.
|
||||
|
||||
<hr>
|
||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->19 Aug 2001<!--webbot bot="Timestamp" endspan i-checksum="14767" --></p>
|
||||
<p>© Copyright Jeremy Siek 2000. Permission to copy, use,
|
||||
modify, sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided "as is"
|
||||
without express or implied warranty, and with no claim as to its suitability for
|
||||
any purpose.</p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<!-- LocalWords: html charset alt gif hpp incrementable const namespace htm
|
||||
-->
|
||||
<!-- LocalWords: struct typename iostream int Siek CopyConstructible pre
|
||||
-->
|
||||
|
@ -1,273 +0,0 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
<title>Filter Iterator Adaptor Documentation</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)"
|
||||
align="center" width="277" height="86">
|
||||
|
||||
<h1>Filter Iterator Adaptor</h1>
|
||||
|
||||
Defined in header
|
||||
<a href="../../boost/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a>
|
||||
|
||||
|
||||
<p>
|
||||
The filter iterator adaptor creates a view of an iterator range in
|
||||
which some elements of the range are skipped over. A <a
|
||||
href="http://www.sgi.com/tech/stl/Predicate.html">Predicate</a>
|
||||
function object controls which elements are skipped. When the
|
||||
predicate is applied to an element, if it returns <tt>true</tt> then
|
||||
the element is retained and if it returns <tt>false</tt> then the
|
||||
element is skipped over.
|
||||
|
||||
|
||||
<h2>Synopsis</h2>
|
||||
|
||||
<pre>
|
||||
namespace boost {
|
||||
template <class Predicate, class BaseIterator, ...>
|
||||
class filter_iterator_generator;
|
||||
|
||||
template <class Predicate, class BaseIterator>
|
||||
typename filter_iterator_generator<Predicate, BaseIterator>::type
|
||||
make_filter_iterator(BaseIterator first, BaseIterator last, const Predicate& p = Predicate());
|
||||
}
|
||||
</pre>
|
||||
|
||||
<hr>
|
||||
|
||||
<h2><a name="filter_iterator_generator">The Filter Iterator Type
|
||||
Generator</a></h2>
|
||||
|
||||
The class <tt>filter_iterator_generator</tt> is a helper class whose
|
||||
purpose is to construct a filter iterator type. The template
|
||||
parameters for this class are the <tt>Predicate</tt> function object
|
||||
type and the <tt>BaseIterator</tt> type that is being wrapped. In
|
||||
most cases the associated types for the wrapped iterator can be
|
||||
deduced from <tt>std::iterator_traits</tt>, but in some situations the
|
||||
user may want to override these types, so there are also template
|
||||
parameters for each of the iterator's associated types.
|
||||
|
||||
<pre>
|
||||
template <class Predicate, class BaseIterator,
|
||||
class Value, class Reference, class Pointer, class Category, class Distance>
|
||||
class filter_iterator_generator
|
||||
{
|
||||
public:
|
||||
typedef <tt><a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> type; // the resulting filter iterator type
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
The following example uses filter iterator to print out all the
|
||||
positive integers in an array.
|
||||
|
||||
<pre>
|
||||
struct is_positive_number {
|
||||
bool operator()(int x) { return 0 < x; }
|
||||
};
|
||||
int main() {
|
||||
int numbers[] = { 0, -1, 4, -3, 5, 8, -2 };
|
||||
const int N = sizeof(numbers)/sizeof(int);
|
||||
|
||||
typedef boost::filter_iterator_generator<is_positive_number, int*, int>::type FilterIter;
|
||||
is_positive_number predicate;
|
||||
FilterIter::policies_type policies(predicate, numbers + N);
|
||||
FilterIter filter_iter_first(numbers, policies);
|
||||
FilterIter filter_iter_last(numbers + N, policies);
|
||||
|
||||
std::copy(filter_iter_first, filter_iter_last, std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
The output is:
|
||||
<pre>
|
||||
4 5 8
|
||||
</pre>
|
||||
|
||||
|
||||
<h3>Template Parameters</h3>
|
||||
|
||||
<Table border>
|
||||
<TR>
|
||||
<TH>Parameter</TH><TH>Description</TH>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><a href="http://www.sgi.com/tech/stl/Predicate.html"><tt>Predicate</tt></a></TD>
|
||||
<TD>The function object that determines which elements are retained and which elements are skipped.
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>BaseIterator</tt></TD>
|
||||
<TD>The iterator type being wrapped. This type must at least be a model
|
||||
of the <a href="http://www.sgi.com/tech/stl/InputIterator">InputIterator</a> concept.</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>Value</tt></TD>
|
||||
<TD>The <tt>value_type</tt> of the resulting iterator,
|
||||
unless const. If const, a conforming compiler strips constness for the
|
||||
<tt>value_type</tt>. Typically the default for this parameter is the
|
||||
appropriate type<a href="#1">[1]</a>.<br> <b>Default:</b>
|
||||
<tt>std::iterator_traits<BaseIterator>::value_type</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>Reference</tt></TD>
|
||||
<TD>The <tt>reference</tt> type of the resulting iterator, and in
|
||||
particular, the result type of <tt>operator*()</tt>. Typically the default for
|
||||
this parameter is the appropriate type.<br> <b>Default:</b> If
|
||||
<tt>Value</tt> is supplied, <tt>Value&</tt> is used. Otherwise
|
||||
<tt>std::iterator_traits<BaseIterator>::reference</tt> is
|
||||
used.</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>Pointer</tt></TD>
|
||||
<TD>The <tt>pointer</tt> type of the resulting iterator, and in
|
||||
particular, the result type of <tt>operator->()</tt>.
|
||||
Typically the default for
|
||||
this parameter is the appropriate type.<br>
|
||||
<b>Default:</b> If <tt>Value</tt> was supplied, then <tt>Value*</tt>,
|
||||
otherwise <tt>std::iterator_traits<BaseIterator>::pointer</tt>.</TD>
|
||||
</TR>
|
||||
|
||||
|
||||
<TR>
|
||||
<TD><tt>Category</tt></TD>
|
||||
<TD>The <tt>iterator_category</tt> type for the resulting iterator.
|
||||
Typically the
|
||||
default for this parameter is the appropriate type. If you override
|
||||
this parameter, do not use <tt>bidirectional_iterator_tag</tt>
|
||||
because filter iterators can not go in reverse.<br>
|
||||
<b>Default:</b> <tt>std::iterator_traits<BaseIterator>::iterator_category</tt></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>Distance</tt></TD>
|
||||
<TD>The <tt>difference_type</tt> for the resulting iterator. Typically the default for
|
||||
this parameter is the appropriate type.<br>
|
||||
<b>Default:</b> <tt>std::iterator_traits<BaseIterator>::difference_type</TD>
|
||||
</TR>
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
<h3>Model of</h3>
|
||||
|
||||
The filter iterator adaptor (the type
|
||||
<tt>filter_iterator_generator<...>::type</tt>) may be a model of <a
|
||||
href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a> or <a
|
||||
href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>
|
||||
depending on the adapted iterator type.
|
||||
|
||||
|
||||
<h3>Members</h3>
|
||||
|
||||
The filter iterator type implements all of the member functions and
|
||||
operators required of the <a
|
||||
href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>
|
||||
concept. In addition it has the following constructor:
|
||||
|
||||
<pre>filter_iterator_generator::type(const BaseIterator& it, const Policies& p = Policies())</pre>
|
||||
|
||||
<p>
|
||||
The policies type has only one public function, which is its constructor:
|
||||
|
||||
<pre>filter_iterator_generator::policies_type(const Predicate& p, const BaseIterator& end)</pre>
|
||||
|
||||
<p>
|
||||
<hr>
|
||||
<p>
|
||||
|
||||
<h2><a name="make_filter_iterator">The Make Filter Iterator Function</a></h2>
|
||||
|
||||
<pre>
|
||||
template <class Predicate, class BaseIterator>
|
||||
typename filter_generator<Predicate, BaseIterator>::type
|
||||
make_filter_iterator(BaseIterator first, BaseIterator last, const Predicate& p = Predicate())
|
||||
</pre>
|
||||
|
||||
This function provides a convenient way to create filter iterators.
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
In this example we print out all numbers in the array that are
|
||||
greater than negative two.
|
||||
|
||||
<pre>
|
||||
int main()
|
||||
{
|
||||
int numbers[] = { 0, -1, 4, -3, 5, 8, -2 };
|
||||
const int N = sizeof(numbers)/sizeof(int);
|
||||
|
||||
std::copy(boost::make_filter_iterator(numbers, numbers + N,
|
||||
std::bind2nd(std::greater<int>(), -2)),
|
||||
boost::make_filter_iterator(numbers + N, numbers + N,
|
||||
std::bind2nd(std::greater<int>(), -2)),
|
||||
std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
|
||||
}
|
||||
</pre>
|
||||
The output is:
|
||||
<pre>
|
||||
0 -1 4 5 8
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
In the next example we print the positive numbers using the
|
||||
<tt>make_filter_iterator()</tt> function.
|
||||
|
||||
<pre>
|
||||
struct is_positive_number {
|
||||
bool operator()(int x) { return 0 < x; }
|
||||
};
|
||||
int main()
|
||||
{
|
||||
int numbers[] = { 0, -1, 4, -3, 5, 8, -2 };
|
||||
const int N = sizeof(numbers)/sizeof(int);
|
||||
|
||||
std::copy(boost::make_filter_iterator<is_positive_number>(numbers, numbers + N),
|
||||
boost::make_filter_iterator<is_positive_number>(numbers + N, numbers + N),
|
||||
std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
The output is:
|
||||
<pre>
|
||||
4 5 8
|
||||
</pre>
|
||||
|
||||
|
||||
<h3>Notes</h3>
|
||||
|
||||
<a name="1">[1]</a> If the compiler does not support partial
|
||||
specialization and the wrapped iterator type is a builtin pointer then
|
||||
the <tt>Value</tt> type must be explicitly specified (don't use the
|
||||
default).
|
||||
|
||||
|
||||
<hr>
|
||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->09 Mar 2001<!--webbot bot="Timestamp" endspan i-checksum="14894" --></p>
|
||||
<p>© Copyright Jeremy Siek 2000. Permission to copy, use,
|
||||
modify, sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided "as is"
|
||||
without express or implied warranty, and with no claim as to its suitability for
|
||||
any purpose.</p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,169 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content="HTML Tidy, see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
|
||||
<title>Function Output Iterator Adaptor Documentation</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align=
|
||||
"center" width="277" height="86">
|
||||
|
||||
<h1>Function Output Iterator Adaptor</h1>
|
||||
Defined in header <a href=
|
||||
"../../boost/function_output_iterator.hpp">boost/function_output_iterator.hpp</a>
|
||||
|
||||
<p>The function output iterator adaptor makes it easier to create
|
||||
custom output iterators. The adaptor takes a <a
|
||||
href="http://www.sgi.com/tech/stl/UnaryFunction.html">Unary
|
||||
Function</a> and creates a model of <a
|
||||
href="http://www.sgi.com/tech/stl/OutputIterator.html">Output
|
||||
Iterator</a>. 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 C++ Standard conforming output
|
||||
iterator is non-trivial, particularly because the proper
|
||||
implementation usually requires a proxy object. On the other hand,
|
||||
creating a function (or function object) is much simpler.
|
||||
|
||||
<h2>Synopsis</h2>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
namespace boost {
|
||||
template <class UnaryFunction>
|
||||
class function_output_iterator;
|
||||
|
||||
template <class UnaryFunction>
|
||||
function_output_iterator<UnaryFunction>
|
||||
make_function_output_iterator(const UnaryFunction& f = UnaryFunction())
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
In this example we create an output iterator that appends
|
||||
each item onto the end of a string, using the <tt>string_appender</tt>
|
||||
function.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/function_output_iterator.hpp>
|
||||
|
||||
struct string_appender {
|
||||
string_appender(std::string& s) : m_str(s) { }
|
||||
void operator()(const std::string& x) const {
|
||||
m_str += x;
|
||||
}
|
||||
std::string& m_str;
|
||||
};
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
std::vector<std::string> x;
|
||||
x.push_back("hello");
|
||||
x.push_back(" ");
|
||||
x.push_back("world");
|
||||
x.push_back("!");
|
||||
|
||||
std::string s = "";
|
||||
std::copy(x.begin(), x.end(),
|
||||
boost::make_function_output_iterator(string_appender(s)));
|
||||
|
||||
std::cout << s << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<h2><a name="function_output_iterator">The Function Output Iterator Class</a></h2>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
template <class UnaryFunction>
|
||||
class function_output_iterator;
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
The <tt>function_output_iterator</tt> class creates an <a
|
||||
href="http://www.sgi.com/tech/stl/OutputIterator.html">Output
|
||||
Iterator</a> out of a
|
||||
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">Unary
|
||||
Function</a>. Each item assigned to the output iterator is passed
|
||||
as an argument to the unary function.
|
||||
|
||||
<h3>Template Parameters</h3>
|
||||
|
||||
<table border>
|
||||
<tr>
|
||||
<th>Parameter
|
||||
|
||||
<th>Description
|
||||
|
||||
<tr>
|
||||
<td><tt>UnaryFunction</tt>
|
||||
|
||||
<td>The function type being wrapped. The return type of the
|
||||
function is not used, so it can be <tt>void</tt>. The
|
||||
function must be a model of <a
|
||||
href="http://www.sgi.com/tech/stl/UnaryFunction.html">Unary
|
||||
Function</a>.</td>
|
||||
</table>
|
||||
|
||||
<h3>Concept Model</h3>
|
||||
The function output iterator class is a model of <a
|
||||
href="http://www.sgi.com/tech/stl/OutputIterator.html">Output
|
||||
Iterator</a>.
|
||||
|
||||
<h2>Members</h3>
|
||||
The function output iterator implements the member functions
|
||||
and operators required of the <a
|
||||
href="http://www.sgi.com/tech/stl/OutputIterator.html">Output
|
||||
Iterator</a> concept. In addition it has the following constructor:
|
||||
<pre>
|
||||
explicit function_output_iterator(const UnaryFunction& f = UnaryFunction())
|
||||
</pre>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<hr>
|
||||
<h2><a name="make_function_output_iterator">The Function Output Iterator Object
|
||||
Generator</a></h2>
|
||||
|
||||
The <tt>make_function_output_iterator()</tt> function provides a
|
||||
more convenient way to create function output iterator objects. The
|
||||
function saves the user the trouble of explicitly writing out the
|
||||
iterator types. If the default argument is used, the function
|
||||
type must be provided as an explicit template argument.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
template <class UnaryFunction>
|
||||
function_output_iterator<UnaryFunction>
|
||||
make_function_output_iterator(const UnaryFunction& f = UnaryFunction())
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>© Copyright Jeremy Siek 2001. Permission to copy, use,
|
||||
modify, sell and distribute this document is granted provided this
|
||||
copyright notice appears in all copies. This document is provided
|
||||
"as is" without express or implied warranty, and with no claim as
|
||||
to its suitability for any purpose.
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,444 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content="HTML Tidy, see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
|
||||
<title>Indirect Iterator Adaptor Documentation</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align=
|
||||
"center" width="277" height="86">
|
||||
|
||||
<h1>Indirect Iterator Adaptor</h1>
|
||||
Defined in header <a href=
|
||||
"../../boost/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a>
|
||||
|
||||
<p>The indirect iterator adaptor augments an iterator by applying an
|
||||
<b>extra</b> dereference inside of <tt>operator*()</tt>. For example, this
|
||||
iterator makes it possible to view a container of pointers or
|
||||
smart-pointers (e.g. <tt>std::list<boost::shared_ptr<foo>
|
||||
></tt>) as if it were a container of the pointed-to type. The following
|
||||
<b>pseudo-code</b> shows the basic idea of the indirect iterator:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
// inside a hypothetical indirect_iterator class...
|
||||
typedef std::iterator_traits<BaseIterator>::value_type Pointer;
|
||||
typedef std::iterator_traits<Pointer>::reference reference;
|
||||
|
||||
reference indirect_iterator::operator*() const {
|
||||
return **this->base_iterator;
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h2>Synopsis</h2>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
namespace boost {
|
||||
template <class BaseIterator,
|
||||
class Value, class Reference, class Category, class Pointer>
|
||||
struct indirect_iterator_generator;
|
||||
|
||||
template <class BaseIterator,
|
||||
class Value, class Reference, class ConstReference,
|
||||
class Category, class Pointer, class ConstPointer>
|
||||
struct indirect_iterator_pair_generator;
|
||||
|
||||
template <class BaseIterator>
|
||||
typename indirect_iterator_generator<BaseIterator>::type
|
||||
make_indirect_iterator(BaseIterator base)
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
<hr>
|
||||
|
||||
<h2><a name="indirect_iterator_generator">The Indirect Iterator Type
|
||||
Generator</a></h2>
|
||||
The <tt>indirect_iterator_generator</tt> template is a <a href=
|
||||
"../../more/generic_programming.html#type_generator">generator</a> of
|
||||
indirect iterator types. The main template parameter for this class is the
|
||||
<tt>BaseIterator</tt> type that is being wrapped. In most cases the type of
|
||||
the elements being pointed to can be deduced using
|
||||
<tt>std::iterator_traits</tt>, but in some situations the user may want to
|
||||
override this type, so there are also template parameters that allow a user
|
||||
to control the <tt>value_type</tt>, <tt>pointer</tt>, and
|
||||
<tt>reference</tt> types of the resulting iterators.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
template <class BaseIterator,
|
||||
class Value, class Reference, class Pointer>
|
||||
class indirect_iterator_generator
|
||||
{
|
||||
public:
|
||||
typedef <tt><a href=
|
||||
"./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> type; // the resulting indirect iterator type
|
||||
};
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>Example</h3>
|
||||
This example uses the <tt>indirect_iterator_generator</tt> to create
|
||||
indirect iterators which dereference the pointers stored in the
|
||||
<tt>pointers_to_chars</tt> array to access the <tt>char</tt>s in the
|
||||
<tt>characters</tt> array.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
#include <boost/config.hpp>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <boost/iterator_adaptors.hpp>
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
char characters[] = "abcdefg";
|
||||
const int N = sizeof(characters)/sizeof(char) - 1; // -1 since characters has a null char
|
||||
char* pointers_to_chars[N]; // at the end.
|
||||
for (int i = 0; i < N; ++i)
|
||||
pointers_to_chars[i] = &characters[i];
|
||||
|
||||
boost::indirect_iterator_generator<char**, char>::type
|
||||
indirect_first(pointers_to_chars), indirect_last(pointers_to_chars + N);
|
||||
|
||||
std::copy(indirect_first, indirect_last, std::ostream_iterator<char>(std::cout, ","));
|
||||
std::cout << std::endl;
|
||||
|
||||
// to be continued...
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>Template Parameters</h3>
|
||||
|
||||
<table border>
|
||||
<tr>
|
||||
<th>Parameter
|
||||
|
||||
<th>Description
|
||||
|
||||
<tr>
|
||||
<td><tt>BaseIterator</tt>
|
||||
|
||||
<td>The iterator type being wrapped. The <tt>value_type</tt>
|
||||
of the base iterator should itself be dereferenceable.
|
||||
The return type of the <tt>operator*</tt> for the
|
||||
<tt>value_type</tt> should match the <tt>Reference</tt> type.
|
||||
|
||||
<tr>
|
||||
<td><tt>Value</tt>
|
||||
|
||||
<td>The <tt>value_type</tt> of the resulting iterator, unless const. If
|
||||
Value is <tt>const X</tt>, a conforming compiler makes the
|
||||
<tt>value_type</tt> <tt><i>non-</i>const X</tt><a href=
|
||||
"iterator_adaptors.htm#1">[1]</a>. Note that if the default
|
||||
is used for <tt>Value</tt>, then there must be a valid specialization
|
||||
of <tt>iterator_traits</tt> for the value type of the base iterator.
|
||||
<br>
|
||||
<b>Default:</b> <tt>std::iterator_traits<<br>
|
||||
std::iterator_traits<BaseIterator>::value_type
|
||||
>::value_type</tt><a href="#2">[2]</a>
|
||||
|
||||
<tr>
|
||||
<td><tt>Reference</tt>
|
||||
|
||||
<td>The <tt>reference</tt> type of the resulting iterator, and in
|
||||
particular, the result type of <tt>operator*()</tt>.<br>
|
||||
<b>Default:</b> <tt>Value&</tt>
|
||||
|
||||
<tr>
|
||||
<td><tt>Pointer</tt>
|
||||
|
||||
<td>The <tt>pointer</tt> type of the resulting iterator, and in
|
||||
particular, the result type of <tt>operator->()</tt>.<br>
|
||||
<b>Default:</b> <tt>Value*</tt>
|
||||
|
||||
<tr>
|
||||
<td><tt>Category</tt>
|
||||
<td>The <tt>iterator_category</tt> type for the resulting iterator.<br>
|
||||
<b>Default:</b>
|
||||
<tt>std::iterator_traits<BaseIterator>::iterator_category</tt>
|
||||
|
||||
</table>
|
||||
|
||||
<h3>Concept Model</h3>
|
||||
The indirect iterator will model whichever <a href=
|
||||
"http://www.sgi.com/tech/stl/Iterators.html">standard iterator
|
||||
concept category</a> is modeled by the base iterator. Thus, if the
|
||||
base iterator is a model of <a href=
|
||||
"http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
|
||||
Access Iterator</a> then so is the resulting indirect iterator. If
|
||||
the base iterator models a more restrictive concept, the resulting
|
||||
indirect iterator will model the same concept <a href="#3">[3]</a>.
|
||||
|
||||
<h3>Members</h3>
|
||||
The indirect iterator type implements the member functions and operators
|
||||
required of the <a href=
|
||||
"http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
|
||||
Iterator</a> concept. In addition it has the following constructor:
|
||||
<pre>
|
||||
explicit indirect_iterator_generator::type(const BaseIterator& it)
|
||||
</pre>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>
|
||||
|
||||
<h2><a name="indirect_iterator_pair_generator">The Indirect Iterator Pair
|
||||
Generator</a></h2>
|
||||
Sometimes a pair of <tt>const</tt>/non-<tt>const</tt> pair of iterators is
|
||||
needed, such as when implementing a container. The
|
||||
<tt>indirect_iterator_pair_generator</tt> class makes it more convenient to
|
||||
create this pair of iterator types.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
template <class BaseIterator,
|
||||
class Value, class Reference, class ConstReference,
|
||||
class Category, class Pointer, class ConstPointer>
|
||||
struct indirect_iterator_pair_generator;
|
||||
{
|
||||
public:
|
||||
typedef <tt><a href=
|
||||
"./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> iterator; // the mutable indirect iterator type
|
||||
typedef <tt><a href=
|
||||
"./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> const_iterator; // the immutable indirect iterator type
|
||||
};
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
// continuing from the last example...
|
||||
|
||||
typedef boost::indirect_iterator_pair_generator<char**,
|
||||
char, char*, char&, const char*, const char&> PairGen;
|
||||
|
||||
char mutable_characters[N];
|
||||
char* pointers_to_mutable_chars[N];
|
||||
for (int i = 0; i < N; ++i)
|
||||
pointers_to_mutable_chars[i] = &mutable_characters[i];
|
||||
|
||||
PairGen::iterator mutable_indirect_first(pointers_to_mutable_chars),
|
||||
mutable_indirect_last(pointers_to_mutable_chars + N);
|
||||
PairGen::const_iterator const_indirect_first(pointers_to_chars),
|
||||
const_indirect_last(pointers_to_chars + N);
|
||||
|
||||
std::transform(const_indirect_first, const_indirect_last,
|
||||
mutable_indirect_first, std::bind1st(std::plus<char>(), 1));
|
||||
|
||||
std::copy(mutable_indirect_first, mutable_indirect_last,
|
||||
std::ostream_iterator<char>(std::cout, ","));
|
||||
std::cout << std::endl;
|
||||
// to be continued...
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>The output is:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
b,c,d,e,f,g,h,
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>Template Parameters</h3>
|
||||
|
||||
<table border>
|
||||
<tr>
|
||||
<th>Parameter
|
||||
|
||||
<th>Description
|
||||
|
||||
<tr>
|
||||
<td><tt>BaseIterator</tt>
|
||||
|
||||
<td>The iterator type being wrapped. The <tt>value_type</tt> of the
|
||||
base iterator should itself be dereferenceable.
|
||||
The return type of the <tt>operator*</tt> for the
|
||||
<tt>value_type</tt> should match the <tt>Reference</tt> type.
|
||||
|
||||
<tr>
|
||||
<td><tt>Value</tt>
|
||||
|
||||
<td>The <tt>value_type</tt> of the resulting iterators.
|
||||
If Value is <tt>const X</tt>, a conforming compiler makes the
|
||||
<tt>value_type</tt> <tt><i>non-</i>const X</tt><a href=
|
||||
"iterator_adaptors.htm#1">[1]</a>. Note that if the default
|
||||
is used for <tt>Value</tt>, then there must be a valid
|
||||
specialization of <tt>iterator_traits</tt> for the value type
|
||||
of the base iterator.<br>
|
||||
|
||||
<b>Default:</b> <tt>std::iterator_traits<<br>
|
||||
std::iterator_traits<BaseIterator>::value_type
|
||||
>::value_type</tt><a href="#2">[2]</a>
|
||||
|
||||
<tr>
|
||||
<td><tt>Reference</tt>
|
||||
|
||||
<td>The <tt>reference</tt> type of the resulting <tt>iterator</tt>, and
|
||||
in particular, the result type of its <tt>operator*()</tt>.<br>
|
||||
<b>Default:</b> <tt>Value&</tt>
|
||||
|
||||
<tr>
|
||||
<td><tt>ConstReference</tt>
|
||||
|
||||
<td>The <tt>reference</tt> type of the resulting
|
||||
<tt>const_iterator</tt>, and in particular, the result type of its
|
||||
<tt>operator*()</tt>.<br>
|
||||
<b>Default:</b> <tt>const Value&</tt>
|
||||
|
||||
<tr>
|
||||
<td><tt>Category</tt>
|
||||
<td>The <tt>iterator_category</tt> type for the resulting iterator.<br>
|
||||
<b>Default:</b>
|
||||
<tt>std::iterator_traits<BaseIterator>::iterator_category</tt>
|
||||
|
||||
<tr>
|
||||
<td><tt>Pointer</tt>
|
||||
|
||||
<td>The <tt>pointer</tt> type of the resulting <tt>iterator</tt>, and
|
||||
in particular, the result type of its <tt>operator->()</tt>.<br>
|
||||
<b>Default:</b> <tt>Value*</tt>
|
||||
|
||||
<tr>
|
||||
<td><tt>ConstPointer</tt>
|
||||
|
||||
<td>The <tt>pointer</tt> type of the resulting <tt>const_iterator</tt>,
|
||||
and in particular, the result type of its <tt>operator->()</tt>.<br>
|
||||
<b>Default:</b> <tt>const Value*</tt>
|
||||
|
||||
</table>
|
||||
|
||||
<h3>Concept Model</h3>
|
||||
|
||||
The indirect iterators will model whichever <a href=
|
||||
"http://www.sgi.com/tech/stl/Iterators.html">standard iterator
|
||||
concept category</a> is modeled by the base iterator. Thus, if the
|
||||
base iterator is a model of <a href=
|
||||
"http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
|
||||
Access Iterator</a> then so are the resulting indirect
|
||||
iterators. If the base iterator models a more restrictive concept,
|
||||
the resulting indirect iterators will model the same concept <a
|
||||
href="#3">[3]</a>.
|
||||
|
||||
|
||||
<h3>Members</h3>
|
||||
The resulting <tt>iterator</tt> and <tt>const_iterator</tt> types implement
|
||||
the member functions and operators required of the <a href=
|
||||
"http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
|
||||
Iterator</a> concept. In addition they support the following constructors:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
explicit indirect_iterator_pair_generator::iterator(const BaseIterator& it)
|
||||
explicit indirect_iterator_pair_generator::const_iterator(const BaseIterator& it)
|
||||
</pre>
|
||||
</blockquote>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>
|
||||
|
||||
<h2><a name="make_indirect_iterator">The Indirect Iterator Object
|
||||
Generator</a></h2>
|
||||
The <tt>make_indirect_iterator()</tt> function provides a more convenient
|
||||
way to create indirect iterator objects. The function saves the user the
|
||||
trouble of explicitly writing out the iterator types.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
template <class BaseIterator>
|
||||
typename indirect_iterator_generator<BaseIterator>::type
|
||||
make_indirect_iterator(BaseIterator base)
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>Example</h3>
|
||||
Here we again print the <tt>char</tt>s from the array <tt>characters</tt>
|
||||
by accessing them through the array of pointers <tt>pointer_to_chars</tt>,
|
||||
but this time we use the <tt>make_indirect_iterator()</tt> function which
|
||||
saves us some typing.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
// continuing from the last example...
|
||||
|
||||
std::copy(boost::make_indirect_iterator(pointers_to_chars),
|
||||
boost::make_indirect_iterator(pointers_to_chars + N),
|
||||
std::ostream_iterator<char>(std::cout, ","));
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
The output is:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
a,b,c,d,e,f,g,
|
||||
</pre>
|
||||
</blockquote>
|
||||
<hr>
|
||||
|
||||
<h3>Notes</h3>
|
||||
|
||||
<p>
|
||||
|
||||
<p><a name="2">[2]</a> If your compiler does not support partial
|
||||
specialization and the base iterator or its <tt>value_type</tt> is a
|
||||
builtin pointer type, you will not be able to use the default for
|
||||
<tt>Value</tt> and will need to specify this type explicitly.
|
||||
|
||||
<p><a name="3">[3]</a>There is a caveat to which concept the
|
||||
indirect iterator can model. If the return type of the
|
||||
<tt>operator*</tt> for the base iterator's value type is not a
|
||||
true reference, then strickly speaking, the indirect iterator can
|
||||
not be a model of <a href=
|
||||
"http://www.sgi.com/tech/stl/ForwardIterator.html">Forward
|
||||
Iterator</a> or any of the concepts that refine it. In this case
|
||||
the <tt>Category</tt> for the indirect iterator should be
|
||||
specified as <tt>std::input_iterator_tag</tt>. However, even in
|
||||
this case, if the base iterator is a random access iterator, the
|
||||
resulting indirect iterator will still satisfy most of the
|
||||
requirements for <a href=
|
||||
"http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
|
||||
Access Iterator</a>.
|
||||
|
||||
<hr>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->18 Sep 2001<!--webbot bot="Timestamp" endspan i-checksum="14941" -->
|
||||
|
||||
|
||||
<p>© Copyright Jeremy Siek and David Abrahams 2001. Permission to
|
||||
copy, use, modify, sell and distribute this document is granted provided
|
||||
this copyright notice appears in all copies. This document is provided "as
|
||||
is" without express or implied warranty, and with no claim as to its
|
||||
suitability for any purpose.
|
||||
<!-- LocalWords: html charset alt gif hpp BaseIterator const namespace struct
|
||||
-->
|
||||
|
||||
<!-- LocalWords: ConstPointer ConstReference typename iostream int abcdefg
|
||||
-->
|
||||
<!-- LocalWords: sizeof PairGen pre Jeremy Siek David Abrahams
|
||||
-->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@ -1,177 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Permutation Iterator Adaptor Documentation</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
<h1>Permutation Iterator Adaptor</h1>
|
||||
<p>Defined in header <a href="../../boost/permutation_iterator.hpp">boost/permutation_iterator.hpp</a></p>
|
||||
<p>The permutation iterator adaptor provides an iterator to a permutation of a given range.
|
||||
(<a href="http://www.cut-the-knot.com/do_you_know/permutation.html">see definition of permutation</a>).
|
||||
The adaptor takes two arguments
|
||||
<ul>
|
||||
<li>an iterator to the range V on which the <a href="http://www.cut-the-knot.com/do_you_know/permutation.html">permutation</a> will be applied</li>
|
||||
<li>the reindexing scheme that defines how the elements of V will be permuted.</li>
|
||||
</ul>
|
||||
|
||||
<p>Note that the permutation iterator is not limited to strict permutations of the given range V.
|
||||
The distance between begin and end of the reindexing iterators is allowed to be smaller compared to the
|
||||
size of the range V, in which case the permutation iterator only provides a permutation of a subrange of V.
|
||||
The indexes neither need to be unique. In this same context, it must be noted that the past the end permutation iterator is
|
||||
completely defined by means of the past-the-end iterator to the indices</p>
|
||||
|
||||
<h2>Synopsis</h2>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
namespace boost {
|
||||
template <class IndexIterator>
|
||||
class permutation_iterator_policies;
|
||||
|
||||
template <class ElementIterator, class IndexIterator>
|
||||
class permutation_iterator_generator;
|
||||
|
||||
template <class ElementIterator, class IndexIterator>
|
||||
typename permutation_iterator_generator<ElementIterator, IndexIterator>::type
|
||||
make_permutation_iterator(ElementIterator& base, IndexIterator& indexing);
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
|
||||
<h2>The Permutation Iterator Generator Class Template</h2>
|
||||
|
||||
<p>The <code>permutation_iterator_generator</code> is a helper class whose purpose
|
||||
is to construct a permutation iterator <strong>type</strong>. This class has
|
||||
two template arguments, the first being the iterator type over the range V, the
|
||||
second being the type of the iterator over the indices.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
template <class ElementIterator, class IndexIterator>
|
||||
class permutation_iterator_generator
|
||||
{
|
||||
public:
|
||||
typedef <a href="iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...> type; // the resulting permutation iterator type
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
|
||||
<h3>Template Parameters</h3>
|
||||
|
||||
<table border>
|
||||
<tr>
|
||||
<th>Parameter</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>ElementIterator</tt></td>
|
||||
<td>The iterator over the elements to be permuted. This type must be a model
|
||||
of <a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">RandomAccessIterator</a></td>
|
||||
</td>
|
||||
|
||||
<tr>
|
||||
<td><tt>IndexIterator</tt></td>
|
||||
<td>The iterator over the new indexing scheme. This type must at least be a model
|
||||
of <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>.
|
||||
The <code>IndexIterator::value_type</code> must be convertible to the
|
||||
<code>ElementIterator::difference_type</code>.</td>
|
||||
</table>
|
||||
|
||||
<h3>Concept Model</h3>
|
||||
The permutation iterator is always a model of the same concept as the IndexIterator.
|
||||
|
||||
<h3>Members</h3>
|
||||
The permutation iterator implements the member functions
|
||||
and operators required for the
|
||||
<a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access Iterator</a>
|
||||
concept. However, the permutation iterator can only meet the complexity guarantees
|
||||
of the same concept as the IndexIterator. Thus for instance, although the permutation
|
||||
iterator provides <code>operator+=(distance)</code>, this operation will take linear time
|
||||
in case the IndexIterator is a model of ForwardIterator instead of amortized constant time.
|
||||
|
||||
<br>
|
||||
|
||||
<h2><a name="make_generator_iterator">The Permutation Iterator Object Generator</a></h2>
|
||||
|
||||
The <code>make_permutation_iterator()</code> function provides a
|
||||
convenient way to create permutation iterator objects. The function
|
||||
saves the user the trouble of explicitly writing out the iterator
|
||||
types.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
template <class ElementIterator, class IndexIterator >
|
||||
typename permutation_iterator_generator<ElementIterator, IndexIterator>::type
|
||||
make_permutation_iterator(ElementIterator& base, IndexIterator& indices);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h2>Example</h2>
|
||||
<blockquote>
|
||||
<pre>
|
||||
using namespace boost;
|
||||
int i = 0;
|
||||
|
||||
typedef std::vector< int > element_range_type;
|
||||
typedef std::list< int > index_type;
|
||||
|
||||
static const int element_range_size = 10;
|
||||
static const int index_size = 4;
|
||||
|
||||
element_range_type elements( element_range_size );
|
||||
for(element_range_type::iterator el_it = elements.begin() ; el_it != elements.end() ; ++el_it) *el_it = std::distance(elements.begin(), el_it);
|
||||
|
||||
index_type indices( index_size );
|
||||
for(index_type::iterator i_it = indices.begin() ; i_it != indices.end() ; ++i_it ) *i_it = element_range_size - index_size + std::distance(indices.begin(), i_it);
|
||||
std::reverse( indices.begin(), indices.end() );
|
||||
|
||||
typedef permutation_iterator_generator< element_range_type::iterator, index_type::iterator >::type permutation_type;
|
||||
permutation_type begin = make_permutation_iterator( elements.begin(), indices.begin() );
|
||||
permutation_type it = begin;
|
||||
permutation_type end = make_permutation_iterator( elements.begin(), indices.end() );
|
||||
|
||||
std::cout << "The original range is : ";
|
||||
std::copy( elements.begin(), elements.end(), std::ostream_iterator< int >( std::cout, " " ) );
|
||||
std::cout << "\n";
|
||||
|
||||
std::cout << "The reindexing scheme is : ";
|
||||
std::copy( indices.begin(), indices.end(), std::ostream_iterator< int >( std::cout, " " ) );
|
||||
std::cout << "\n";
|
||||
|
||||
std::cout << "The permutated range is : ";
|
||||
std::copy( begin, end, std::ostream_iterator< int >( std::cout, " " ) );
|
||||
std::cout << "\n";
|
||||
|
||||
std::cout << "Elements at even indices in the permutation : ";
|
||||
it = begin;
|
||||
for(i = 0; i < index_size / 2 ; ++i, it+=2 ) std::cout << *it << " ";
|
||||
std::cout << "\n";
|
||||
|
||||
std::cout << "Permutation backwards : ";
|
||||
it = begin + (index_size);
|
||||
assert( it != begin );
|
||||
for( ; it-- != begin ; ) std::cout << *it << " ";
|
||||
std::cout << "\n";
|
||||
|
||||
std::cout << "Iterate backward with stride 2 : ";
|
||||
it = begin + (index_size - 1);
|
||||
for(i = 0 ; i < index_size / 2 ; ++i, it-=2 ) std::cout << *it << " ";
|
||||
std::cout << "\n";
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<br><br><br><hr>
|
||||
Thanks: The permutation iterator is only a small addition to the superb iterator adaptors
|
||||
library of David Abrahams and Jeremy Siek.
|
||||
<br><br>
|
||||
|
||||
Copyright 2001 Toon Knapen.
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,391 +0,0 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
<title>Projection Iterator Adaptor Documentation</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)"
|
||||
align="center" width="277" height="86">
|
||||
|
||||
<h1>Projection Iterator Adaptor</h1>
|
||||
|
||||
Defined in header
|
||||
<a href="../../boost/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a>
|
||||
|
||||
<p>
|
||||
The projection iterator adaptor is similar to the <a
|
||||
href="./transform_iterator.htm">transform iterator adaptor</a> in that
|
||||
its <tt>operator*()</tt> applies some function to the result of
|
||||
dereferencing the base iterator and then returns the result. The
|
||||
difference is that the function must return a reference to some
|
||||
existing object (for example, a data member within the
|
||||
<tt>value_type</tt> of the base iterator). The following
|
||||
<b>pseudo-code</b> gives the basic idea. The data member <tt>p</tt> is
|
||||
the function object.
|
||||
|
||||
<pre>
|
||||
reference projection_iterator::operator*() const {
|
||||
return this->p(*this->base_iterator);
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h2>Synopsis</h2>
|
||||
|
||||
<pre>
|
||||
namespace boost {
|
||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator>
|
||||
struct projection_iterator_generator;
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>,
|
||||
class BaseIterator, class ConstBaseIterator>
|
||||
struct projection_iterator_pair_generator;
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator>
|
||||
typename projection_iterator_generator<AdaptableUnaryFunction, BaseIterator>::type
|
||||
make_projection_iterator(BaseIterator base,
|
||||
const AdaptableUnaryFunction& p = AdaptableUnaryFunction())
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class ConstBaseIterator>
|
||||
typename projection_iterator_generator<AdaptableUnaryFunction, ConstBaseIterator>::type
|
||||
make_const_projection_iterator(ConstBaseIterator base,
|
||||
const AdaptableUnaryFunction& p = AdaptableUnaryFunction())
|
||||
}
|
||||
</pre>
|
||||
|
||||
<hr>
|
||||
|
||||
<h2><a name="projection_iterator_generator">The Projection Iterator Type
|
||||
Generator</a></h2>
|
||||
|
||||
The class <tt>projection_iterator_generator</tt> is a helper class
|
||||
whose purpose is to construct an projection iterator type. The main
|
||||
template parameter for this class is the <a
|
||||
href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html"><tt>AdaptableUnaryFunction</tt></a>
|
||||
function object type and the <tt>BaseIterator</tt> type that is being
|
||||
wrapped.
|
||||
|
||||
<pre>
|
||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator>
|
||||
class projection_iterator_generator
|
||||
{
|
||||
public:
|
||||
typedef <tt><a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> type; // the resulting projection iterator type
|
||||
};
|
||||
</pre>
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
In the following example we have a list of personnel records. Each
|
||||
record has an employee's name and ID number. We want to be able to
|
||||
traverse through the list accessing either the name or the ID numbers
|
||||
of the employees using the projection iterator so we create the
|
||||
function object classes <tt>select_name</tt> and
|
||||
<tt>select_ID</tt>. We then use the
|
||||
<tt>projection_iterator_generator</tt> class to create a projection
|
||||
iterator and use it to print out the names of the employees.
|
||||
|
||||
<pre>
|
||||
#include <boost/config.hpp>
|
||||
#include <list>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <boost/iterator_adaptors.hpp>
|
||||
|
||||
struct personnel_record {
|
||||
personnel_record(std::string n, int id) : m_name(n), m_ID(id) { }
|
||||
std::string m_name;
|
||||
int m_ID;
|
||||
};
|
||||
|
||||
struct select_name {
|
||||
typedef personnel_record argument_type;
|
||||
typedef std::string result_type;
|
||||
const std::string& operator()(const personnel_record& r) const {
|
||||
return r.m_name;
|
||||
}
|
||||
std::string& operator()(personnel_record& r) const {
|
||||
return r.m_name;
|
||||
}
|
||||
};
|
||||
|
||||
struct select_ID {
|
||||
typedef personnel_record argument_type;
|
||||
typedef int result_type;
|
||||
const int& operator()(const personnel_record& r) const {
|
||||
return r.m_ID;
|
||||
}
|
||||
int& operator()(personnel_record& r) const {
|
||||
return r.m_ID;
|
||||
}
|
||||
};
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
std::list<personnel_record> personnel_list;
|
||||
|
||||
personnel_list.push_back(personnel_record("Barney", 13423));
|
||||
personnel_list.push_back(personnel_record("Fred", 12343));
|
||||
personnel_list.push_back(personnel_record("Wilma", 62454));
|
||||
personnel_list.push_back(personnel_record("Betty", 20490));
|
||||
|
||||
// Example of using projection_iterator_generator
|
||||
// to print out the names in the personnel list.
|
||||
|
||||
boost::projection_iterator_generator<select_name,
|
||||
std::list<personnel_record>::iterator>::type
|
||||
personnel_first(personnel_list.begin()),
|
||||
personnel_last(personnel_list.end());
|
||||
|
||||
std::copy(personnel_first, personnel_last,
|
||||
std::ostream_iterator<std::string>(std::cout, "\n"));
|
||||
std::cout << std::endl;
|
||||
|
||||
// to be continued...
|
||||
</pre>
|
||||
The output for this part is:
|
||||
<pre>
|
||||
Barney
|
||||
Fred
|
||||
Wilma
|
||||
Betty
|
||||
</pre>
|
||||
|
||||
<h3>Template Parameters</h3>
|
||||
|
||||
<Table border>
|
||||
<TR>
|
||||
<TH>Parameter</TH><TH>Description</TH>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html"><tt>AdaptableUnaryFunction</tt></a></TD>
|
||||
<TD>The type of the function object. The <tt>argument_type</tt> of the
|
||||
function must match the value type of the base iterator. The function
|
||||
should return a reference to the function's <tt>result_type</tt>.
|
||||
The <tt>result_type</tt> will be the resulting iterator's <tt>value_type</tt>.
|
||||
</TD>
|
||||
</TD>
|
||||
|
||||
<TR>
|
||||
<TD><tt>BaseIterator</tt></TD>
|
||||
<TD>The iterator type being wrapped.</TD>
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
</Table>
|
||||
|
||||
<h3>Model of</h3>
|
||||
|
||||
If the base iterator is a model of <a
|
||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
|
||||
Access Iterator</a> then so is the resulting projection iterator. If
|
||||
the base iterator supports less functionality than this the resulting
|
||||
projection iterator will also support less functionality.
|
||||
|
||||
<h3>Members</h3>
|
||||
|
||||
The projection iterator type implements the member functions and
|
||||
operators required of the <a
|
||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
|
||||
Access Iterator</a> concept.
|
||||
In addition it has the following constructor:
|
||||
|
||||
<pre>
|
||||
projection_iterator_generator::type(const BaseIterator& it,
|
||||
const AdaptableUnaryFunction& p = AdaptableUnaryFunction())
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
<hr>
|
||||
<p>
|
||||
|
||||
<h2><a name="projection_iterator_pair_generator">The Projection Iterator Pair
|
||||
Generator</a></h2>
|
||||
|
||||
Sometimes a mutable/const pair of iterator types is needed, such as
|
||||
when implementing a container type. The
|
||||
<tt>projection_iterator_pair_generator</tt> class makes it more
|
||||
convenient to create this pair of iterator types.
|
||||
|
||||
<pre>
|
||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator, class ConstBaseIterator>
|
||||
class projection_iterator_pair_generator
|
||||
{
|
||||
public:
|
||||
typedef <tt><a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> iterator; // the mutable projection iterator type
|
||||
typedef <tt><a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> const_iterator; // the immutable projection iterator type
|
||||
};
|
||||
</pre>
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
In this part of the example we use the
|
||||
<tt>projection_iterator_pair_generator</tt> to create a mutable/const
|
||||
pair of projection iterators that access the ID numbers of the
|
||||
personnel. We use the mutable iterator to re-index the ID numbers from
|
||||
zero. We then use the constant iterator to print the ID numbers out.
|
||||
|
||||
<pre>
|
||||
// continuing from the last example...
|
||||
|
||||
typedef boost::projection_iterator_pair_generator<select_ID,
|
||||
std::list<personnel_record>::iterator,
|
||||
std::list<personnel_record>::const_iterator> PairGen;
|
||||
|
||||
PairGen::iterator ID_first(personnel_list.begin()),
|
||||
ID_last(personnel_list.end());
|
||||
|
||||
int new_id = 0;
|
||||
while (ID_first != ID_last) {
|
||||
*ID_first = new_id++;
|
||||
++ID_first;
|
||||
}
|
||||
|
||||
PairGen::const_iterator const_ID_first(personnel_list.begin()),
|
||||
const_ID_last(personnel_list.end());
|
||||
|
||||
std::copy(const_ID_first, const_ID_last,
|
||||
std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
// to be continued...
|
||||
</pre>
|
||||
The output is:
|
||||
<pre>
|
||||
0 1 2 3
|
||||
</pre>
|
||||
|
||||
<h3>Template Parameters</h3>
|
||||
|
||||
<Table border>
|
||||
<TR>
|
||||
<TH>Parameter</TH><TH>Description</TH>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html"><tt>AdaptableUnaryFunction</tt></a></TD>
|
||||
<TD>The type of the function object. The <tt>argument_type</tt> of the
|
||||
function must match the value type of the base iterator. The function
|
||||
should return a true reference to the function's <tt>result_type</tt>.
|
||||
The <tt>result_type</tt> will be the resulting iterator's <tt>value_type</tt>.
|
||||
</TD>
|
||||
</TD>
|
||||
|
||||
<TR>
|
||||
<TD><tt>BaseIterator</tt></TD>
|
||||
<TD>The mutable iterator type being wrapped.</TD>
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>ConstBaseIterator</tt></TD>
|
||||
<TD>The constant iterator type being wrapped.</TD>
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
</Table>
|
||||
|
||||
<h3>Model of</h3>
|
||||
|
||||
If the base iterator types model the <a
|
||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
|
||||
Access Iterator</a> then so do the resulting projection iterator
|
||||
types. If the base iterators support less functionality the
|
||||
resulting projection iterator types will also support less
|
||||
functionality. The resulting <tt>iterator</tt> type is mutable, and
|
||||
the resulting <tt>const_iterator</tt> type is constant.
|
||||
|
||||
<h3>Members</h3>
|
||||
|
||||
The resulting <tt>iterator</tt> and <tt>const_iterator</tt> types
|
||||
implements the member functions and operators required of the <a
|
||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
|
||||
Access Iterator</a> concept. In addition they support the following
|
||||
constructors:
|
||||
|
||||
<pre>
|
||||
projection_iterator_pair_generator::iterator(const BaseIterator& it,
|
||||
const AdaptableUnaryFunction& p = AdaptableUnaryFunction())</pre>
|
||||
|
||||
<pre>
|
||||
projection_iterator_pair_generator::const_iterator(const BaseIterator& it,
|
||||
const AdaptableUnaryFunction& p = AdaptableUnaryFunction())
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
<hr>
|
||||
<p>
|
||||
|
||||
<h2><a name="make_projection_iterator">The Projection Iterator Object Generators</a></h2>
|
||||
|
||||
The <tt>make_projection_iterator()</tt> and
|
||||
<tt>make_const_projection_iterator()</tt> functions provide a more
|
||||
convenient way to create projection iterator objects. The functions
|
||||
save the user the trouble of explicitly writing out the iterator
|
||||
types.
|
||||
|
||||
<pre>
|
||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator>
|
||||
typename projection_iterator_generator<AdaptableUnaryFunction, BaseIterator>::type
|
||||
make_projection_iterator(BaseIterator base,
|
||||
const AdaptableUnaryFunction& p = AdaptableUnaryFunction())
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class ConstBaseIterator>
|
||||
typename projection_iterator_generator<AdaptableUnaryFunction, ConstBaseIterator>::type
|
||||
make_const_projection_iterator(ConstBaseIterator base,
|
||||
const AdaptableUnaryFunction& p = AdaptableUnaryFunction())
|
||||
</pre>
|
||||
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
In this part of the example, we again print out the names of the
|
||||
personnel, but this time we use the
|
||||
<tt>make_const_projection_iterator()</tt> function to save some typing.
|
||||
|
||||
<pre>
|
||||
// continuing from the last example...
|
||||
|
||||
std::copy
|
||||
(boost::make_const_projection_iterator<select_name>(personnel_list.begin()),
|
||||
boost::make_const_projection_iterator<select_name>(personnel_list.end()),
|
||||
std::ostream_iterator<std::string>(std::cout, "\n"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
The output is:
|
||||
<pre>
|
||||
Barney
|
||||
Fred
|
||||
Wilma
|
||||
Betty
|
||||
</pre>
|
||||
|
||||
<hr>
|
||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->19 Aug 2001<!--webbot bot="Timestamp" endspan i-checksum="14767" --></p>
|
||||
<p>© Copyright Jeremy Siek 2000. Permission to copy, use,
|
||||
modify, sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided "as is"
|
||||
without express or implied warranty, and with no claim as to its suitability for
|
||||
any purpose.</p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<!-- LocalWords: html charset alt gif hpp BaseIterator const namespace struct
|
||||
-->
|
||||
<!-- LocalWords: ConstPointer ConstReference typename iostream int abcdefg
|
||||
-->
|
||||
<!-- LocalWords: sizeof PairGen pre Siek htm AdaptableUnaryFunction
|
||||
-->
|
||||
<!-- LocalWords: ConstBaseIterator
|
||||
-->
|
@ -1,331 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content="HTML Tidy, see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
|
||||
<title>Reverse Iterator Adaptor Documentation</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align=
|
||||
"center" width="277" height="86">
|
||||
|
||||
<h1>Reverse Iterator Adaptor</h1>
|
||||
Defined in header <a href=
|
||||
"../../boost/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a>
|
||||
|
||||
<p>The reverse iterator adaptor flips the direction of a base iterator's
|
||||
motion. Invoking <tt>operator++()</tt> moves the base iterator backward and
|
||||
invoking <tt>operator--()</tt> moves the base iterator forward. The Boost
|
||||
reverse iterator adaptor is better to use than the
|
||||
<tt>std::reverse_iterator</tt> 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.
|
||||
|
||||
<h2>Synopsis</h2>
|
||||
<pre>
|
||||
namespace boost {
|
||||
template <class <a href=
|
||||
"http://www.sgi.com/tech/stl/BidirectionalIterator.html">BidirectionalIterator</a>,
|
||||
class Value, class Reference, class Pointer, class Category, class Distance>
|
||||
struct reverse_iterator_generator;
|
||||
|
||||
template <class <a href=
|
||||
"http://www.sgi.com/tech/stl/BidirectionalIterator.html">BidirectionalIterator</a>>
|
||||
typename reverse_iterator_generator<BidirectionalIterator>::type
|
||||
make_reverse_iterator(BidirectionalIterator base)
|
||||
}
|
||||
</pre>
|
||||
<hr>
|
||||
|
||||
<h2><a name="reverse_iterator_generator">The Reverse Iterator Type
|
||||
Generator</a></h2>
|
||||
The <tt>reverse_iterator_generator</tt> template is a <a href=
|
||||
"../../more/generic_programming.html#type_generator">generator</a> of
|
||||
reverse iterator types. The main template parameter for this class is the
|
||||
base <tt>BidirectionalIterator</tt> type that is being adapted. In most
|
||||
cases the associated types of the base iterator can be deduced using
|
||||
<tt>std::iterator_traits</tt>, but in some situations the user may want to
|
||||
override these types, so there are also template parameters for the base
|
||||
iterator's associated types.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
template <class <a href=
|
||||
"http://www.sgi.com/tech/stl/BidirectionalIterator.html">BidirectionalIterator</a>,
|
||||
class Value, class Reference, class Pointer, class Category, class Distance>
|
||||
class reverse_iterator_generator
|
||||
{
|
||||
public:
|
||||
typedef <tt><a href=
|
||||
"./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> type; // the resulting reverse iterator type
|
||||
};
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>Example</h3>
|
||||
In this example we sort a sequence of letters and then output the sequence
|
||||
in descending order using reverse iterators.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
#include <boost/config.hpp>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <boost/iterator_adaptors.hpp>
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
char letters[] = "hello world!";
|
||||
const int N = sizeof(letters)/sizeof(char) - 1;
|
||||
std::cout << "original sequence of letters:\t"
|
||||
<< letters << std::endl;
|
||||
|
||||
std::sort(letters, letters + N);
|
||||
|
||||
// Use reverse_iterator_generator to print a sequence
|
||||
// of letters in reverse order.
|
||||
|
||||
boost::reverse_iterator_generator<char*>::type
|
||||
reverse_letters_first(letters + N),
|
||||
reverse_letters_last(letters);
|
||||
|
||||
std::cout << "letters in descending order:\t";
|
||||
std::copy(reverse_letters_first, reverse_letters_last,
|
||||
std::ostream_iterator<char>(std::cout));
|
||||
std::cout << std::endl;
|
||||
|
||||
// to be continued...
|
||||
</pre>
|
||||
</blockquote>
|
||||
The output is:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
original sequence of letters: hello world!
|
||||
letters in descending order: wroolllhed!
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>Template Parameters</h3>
|
||||
|
||||
<table border>
|
||||
<tr>
|
||||
<th>Parameter
|
||||
|
||||
<th>Description
|
||||
|
||||
<tr>
|
||||
<td><tt><a href=
|
||||
"http://www.sgi.com/tech/stl/BidirectionalIterator.html">BidirectionalIterator</a></tt>
|
||||
|
||||
|
||||
<td>The iterator type being wrapped.
|
||||
|
||||
<tr>
|
||||
<td><tt>Value</tt>
|
||||
|
||||
<td>The value-type of the base iterator and the resulting reverse
|
||||
iterator.<br>
|
||||
<b>Default:</b><tt>std::iterator_traits<BidirectionalIterator>::value_type</tt>
|
||||
|
||||
|
||||
<tr>
|
||||
<td><tt>Reference</tt>
|
||||
|
||||
<td>The <tt>reference</tt> type of the resulting iterator, and in
|
||||
particular, the result type of <tt>operator*()</tt>.<br>
|
||||
<b>Default:</b> If <tt>Value</tt> is supplied, <tt>Value&</tt> is
|
||||
used. Otherwise
|
||||
<tt>std::iterator_traits<BidirectionalIterator>::reference</tt>
|
||||
is used.
|
||||
|
||||
<tr>
|
||||
<td><tt>Pointer</tt>
|
||||
|
||||
<td>The <tt>pointer</tt> type of the resulting iterator, and in
|
||||
particular, the result type of <tt>operator->()</tt>.<br>
|
||||
<b>Default:</b> If <tt>Value</tt> was supplied, then <tt>Value*</tt>,
|
||||
otherwise
|
||||
<tt>std::iterator_traits<BidirectionalIterator>::pointer</tt>.
|
||||
|
||||
<tr>
|
||||
<td><tt>Category</tt>
|
||||
|
||||
<td>The <tt>iterator_category</tt> type for the resulting iterator.<br>
|
||||
<b>Default:</b>
|
||||
<tt>std::iterator_traits<BidirectionalIterator>::iterator_category</tt>
|
||||
|
||||
|
||||
<tr>
|
||||
<td><tt>Distance</tt>
|
||||
|
||||
<td>The <tt>difference_type</tt> for the resulting iterator.<br>
|
||||
<b>Default:</b>
|
||||
<tt>std::iterator_traits<BidirectionalIterator&gt::difference_type</tt>
|
||||
|
||||
</table>
|
||||
|
||||
<h3>Concept Model</h3>
|
||||
The indirect iterator will model whichever <a href=
|
||||
"http://www.sgi.com/tech/stl/Iterators.html">standard iterator concept
|
||||
category</a> is modeled by the base iterator. Thus, if the base iterator is
|
||||
a model of <a href=
|
||||
"http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
|
||||
Iterator</a> then so is the resulting indirect iterator. If the base
|
||||
iterator models a more restrictive concept, the resulting indirect iterator
|
||||
will model the same concept. The base iterator must be at least a <a href=
|
||||
"http://www.sgi.com/tech/stl/BidirectionalIterator.html">Bidirectional
|
||||
Iterator</a>
|
||||
|
||||
<h3>Members</h3>
|
||||
The reverse iterator type implements the member functions and operators
|
||||
required of the <a href=
|
||||
"http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
|
||||
Iterator</a> concept. In addition it has the following constructor:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
reverse_iterator_generator::type(const BidirectionalIterator& it)
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>
|
||||
|
||||
<h2><a name="make_reverse_iterator">The Reverse Iterator Object
|
||||
Generator</a></h2>
|
||||
The <tt>make_reverse_iterator()</tt> function provides a more convenient
|
||||
way to create reverse iterator objects. The function saves the user the
|
||||
trouble of explicitly writing out the iterator types.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
template <class BidirectionalIterator>
|
||||
typename reverse_iterator_generator<BidirectionalIterator>::type
|
||||
make_reverse_iterator(BidirectionalIterator base);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>Example</h3>
|
||||
In this part of the example we use <tt>make_reverse_iterator()</tt> to
|
||||
print the sequence of letters in reverse-reverse order, which is the
|
||||
original order.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
// continuing from the previous example...
|
||||
|
||||
std::cout << "letters in ascending order:\t";
|
||||
std::copy(boost::make_reverse_iterator(reverse_letters_last),
|
||||
boost::make_reverse_iterator(reverse_letters_first),
|
||||
std::ostream_iterator<char>(std::cout));
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
The output is:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
letters in ascending order: !dehllloorw
|
||||
</pre>
|
||||
</blockquote>
|
||||
<hr>
|
||||
|
||||
<h2><a name="interactions">Constant/Mutable Iterator Interactions</a></h2>
|
||||
|
||||
<p>One failing of the standard <tt><a
|
||||
href="http://www.sgi.com/tech/stl/ReverseIterator.html">reverse_iterator</a></tt>
|
||||
adaptor is that it doesn't properly support interactions between adapted
|
||||
<tt>const</tt> and non-<tt>const</tt> iterators. For example:
|
||||
<blockquote>
|
||||
<pre>
|
||||
#include <vector>
|
||||
|
||||
template <class T> void convert(T x) {}
|
||||
|
||||
// Test interactions of a matched pair of random access iterators
|
||||
template <class Iterator, class ConstIterator>
|
||||
void test_interactions(Iterator i, ConstIterator ci)
|
||||
{
|
||||
bool eq = i == ci; // comparisons
|
||||
bool ne = i != ci;
|
||||
bool lt = i < ci;
|
||||
bool le = i <= ci;
|
||||
bool gt = i > ci;
|
||||
bool ge = i >= ci;
|
||||
std::size_t distance = i - ci; // difference
|
||||
ci = i; // assignment
|
||||
ConstIterator ci2(i); // construction
|
||||
convert<ConstIterator>(i); // implicit conversion
|
||||
}
|
||||
|
||||
void f()
|
||||
{
|
||||
typedef std::vector<int> vec;
|
||||
vec v;
|
||||
const vec& cv;
|
||||
|
||||
test_interactions(v.begin(), cv.begin()); // <font color="#007F00">OK</font>
|
||||
test_interactions(v.rbegin(), cv.rbegin()); // <font color="#FF0000">ERRORS ON EVERY TEST!!</font>
|
||||
</pre>
|
||||
</blockquote>
|
||||
Reverse iterators created with <tt>boost::reverse_iterator_generator</tt> don't have this problem, though:
|
||||
<blockquote>
|
||||
<pre>
|
||||
typedef boost::reverse_iterator_generator<vec::iterator>::type ri;
|
||||
typedef boost::reverse_iterator_generator<vec::const_iterator>::type cri;
|
||||
test_interactions(ri(v.begin()), cri(cv.begin())); // <font color="#007F00">OK!!</font>
|
||||
</pre>
|
||||
</blockquote>
|
||||
Or, more simply,
|
||||
<blockquote>
|
||||
<pre>
|
||||
test_interactions(
|
||||
boost::make_reverse_iterator(v.begin()),
|
||||
boost::make_reverse_iterator(cv.begin())); // <font color="#007F00">OK!!</font>
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>If you are wondering why there is no
|
||||
<tt>reverse_iterator_pair_generator</tt> in the manner of <tt><a
|
||||
href="projection_iterator.htm#projection_iterator_pair_generator">projection_iterator_pair_generator</a></tt>,
|
||||
the answer is simple: we tried it, but found that in practice it took
|
||||
<i>more</i> typing to use <tt>reverse_iterator_pair_generator</tt> than to
|
||||
simply use <tt>reverse_iterator_generator</tt> twice!<br><br>
|
||||
|
||||
<hr>
|
||||
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->19 Aug 2001<!--webbot bot="Timestamp" endspan i-checksum="14767" -->
|
||||
|
||||
|
||||
<p>© Copyright Jeremy Siek 2000. Permission to copy, use, modify, sell
|
||||
and distribute this document is granted provided this copyright notice
|
||||
appears in all copies. This document is provided "as is" without express or
|
||||
implied warranty, and with no claim as to its suitability for any purpose.
|
||||
<!-- LocalWords: html charset alt gif hpp BidirectionalIterator const namespace struct
|
||||
-->
|
||||
|
||||
<!-- LocalWords: ConstPointer ConstReference typename iostream int abcdefg
|
||||
-->
|
||||
<!-- LocalWords: sizeof PairGen pre Siek wroolllhed dehllloorw
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,223 +0,0 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
<title>Transform Iterator Adaptor Documentation</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)"
|
||||
align="center" width="277" height="86">
|
||||
|
||||
<h1>Transform Iterator Adaptor</h1>
|
||||
|
||||
Defined in header
|
||||
<a href="../../boost/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a>
|
||||
|
||||
<p>
|
||||
The transform iterator adaptor augments an iterator by applying some
|
||||
function object to the result of dereferencing the iterator. In other
|
||||
words, the <tt>operator*</tt> of the transform iterator first
|
||||
dereferences the base iterator, passes the result of this to the
|
||||
function object, and then returns the result. The following
|
||||
<b>pseudo-code</b> shows the basic idea:
|
||||
|
||||
<pre>
|
||||
value_type transform_iterator::operator*() const {
|
||||
return this->f(*this->base_iterator);
|
||||
}
|
||||
</pre>
|
||||
|
||||
All of the other operators of the transform iterator behave in the
|
||||
same fashion as those of the base iterator.
|
||||
|
||||
|
||||
<h2>Synopsis</h2>
|
||||
|
||||
<pre>
|
||||
namespace boost {
|
||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator>
|
||||
class transform_iterator_generator;
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator>
|
||||
typename transform_iterator_generator<AdaptableUnaryFunction,Iterator>::type
|
||||
make_transform_iterator(BaseIterator base, const AdaptableUnaryFunction& f = AdaptableUnaryFunction());
|
||||
}
|
||||
</pre>
|
||||
|
||||
<hr>
|
||||
|
||||
<h2><a name="transform_iterator_generator">The Transform Iterator Type
|
||||
Generator</a></h2>
|
||||
|
||||
The class <tt>transform_iterator_generator</tt> is a helper class whose
|
||||
purpose is to construct a transform iterator type. The template
|
||||
parameters for this class are the <tt>AdaptableUnaryFunction</tt> function object
|
||||
type and the <tt>BaseIterator</tt> type that is being wrapped.
|
||||
|
||||
<pre>
|
||||
template <class AdaptableUnaryFunction, class Iterator>
|
||||
class transform_iterator_generator
|
||||
{
|
||||
public:
|
||||
typedef <a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...> type;
|
||||
};
|
||||
</pre>
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
<p>
|
||||
The following is an example of how to use the
|
||||
<tt>transform_iterator_generator</tt> class to iterate through a range
|
||||
of numbers, multiplying each of them by 2 when they are dereferenced.
|
||||
The <tt>boost::binder1st</tt> class is used instead of the standard
|
||||
one because tranform iterator requires the function object to be
|
||||
Default Constructible.
|
||||
|
||||
<p>
|
||||
<PRE>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <boost/iterator_adaptors.hpp>
|
||||
|
||||
// definition of class boost::binder1st and function boost::bind1st() ...
|
||||
|
||||
int
|
||||
main(int, char*[])
|
||||
{
|
||||
int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||
|
||||
typedef boost::binder1st< std::multiplies<int> > Function;
|
||||
typedef boost::transform_iterator_generator<Function, int*>::type doubling_iterator;
|
||||
|
||||
doubling_iterator i(x, boost::bind1st(std::multiplies<int>(), 2)),
|
||||
i_end(x + sizeof(x)/sizeof(int), boost::bind1st(std::multiplies<int>(), 2));
|
||||
|
||||
std::cout << "multiplying the array by 2:" << std::endl;
|
||||
while (i != i_end)
|
||||
std::cout << *i++ << " ";
|
||||
std::cout << std::endl;
|
||||
|
||||
// to be continued...
|
||||
</PRE>
|
||||
The output from this part is:
|
||||
<pre>
|
||||
2 4 6 8 10 12 14 16
|
||||
</pre>
|
||||
|
||||
<h3>Template Parameters</h3>
|
||||
|
||||
<Table border>
|
||||
<TR>
|
||||
<TH>Parameter</TH><TH>Description</TH>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><a
|
||||
href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html"><tt>AdaptableUnaryFunction</tt></a></TD>
|
||||
<TD>The function object that transforms each element in the iterator
|
||||
range. The <tt>argument_type</tt> of the function object must match
|
||||
the value type of the base iterator. The <tt>result_type</tt> of the
|
||||
function object will be the resulting iterator's
|
||||
<tt>value_type</tt>. If you want the resulting iterator to behave as
|
||||
an iterator, the result of the function should be solely a function of
|
||||
its argument. Also, the function object must be <a
|
||||
href="http://www.sgi.com/tech/stl/DefaultConstructible.html"> Default
|
||||
Constructible</a> (which many of the standard function objects are not).</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>BaseIterator</tt></TD>
|
||||
<TD>The iterator type being wrapped. This type must at least be a model
|
||||
of the <a href="http://www.sgi.com/tech/stl/InputIterator">InputIterator</a> concept.</TD>
|
||||
</TR>
|
||||
|
||||
</Table>
|
||||
|
||||
<h3>Model of</h3>
|
||||
|
||||
The transform iterator adaptor (the type
|
||||
<tt>transform_iterator_generator<...>::type</tt>) is a model of <a
|
||||
href="http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a><a href="#1">[1]</a>.
|
||||
|
||||
|
||||
<h3>Members</h3>
|
||||
|
||||
The transform iterator type implements the member functions and
|
||||
operators required of the <a
|
||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access Iterator</a>
|
||||
concept, except that the <tt>reference</tt> type is the same as the <tt>value_type</tt>
|
||||
so <tt>operator*()</tt> returns by-value. In addition it has the following constructor:
|
||||
|
||||
<pre>
|
||||
transform_iterator_generator::type(const BaseIterator& it,
|
||||
const AdaptableUnaryFunction& f = AdaptableUnaryFunction())
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
<hr>
|
||||
<p>
|
||||
|
||||
|
||||
<h2><a name="make_transform_iterator">The Transform Iterator Object Generator</a></h2>
|
||||
|
||||
<pre>
|
||||
template <class AdaptableUnaryFunction, class BaseIterator>
|
||||
typename transform_iterator_generator<AdaptableUnaryFunction,BaseIterator>::type
|
||||
make_transform_iterator(BaseIterator base,
|
||||
const AdaptableUnaryFunction& f = AdaptableUnaryFunction());
|
||||
</pre>
|
||||
|
||||
This function provides a convenient way to create transform iterators.
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
Continuing from the previous example, we use the <tt>make_transform_iterator()</tt>
|
||||
function to add four to each element of the array.
|
||||
|
||||
<pre>
|
||||
std::cout << "adding 4 to each element in the array:" << std::endl;
|
||||
|
||||
std::copy(boost::make_transform_iterator(x, boost::bind1st(std::plus<int>(), 4)),
|
||||
boost::make_transform_iterator(x + N, boost::bind1st(std::plus<int>(), 4)),
|
||||
std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
The output from this part is:
|
||||
<pre>
|
||||
5 6 7 8 9 10 11 12
|
||||
</pre>
|
||||
|
||||
<h3>Notes</h3>
|
||||
|
||||
|
||||
<a name="1">[1]</a> If the base iterator is a model of <a
|
||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access Iterator</a>
|
||||
then the transform iterator will also suppport most of the
|
||||
functionality required by the Random Access Iterator concept. However, a
|
||||
transform iterator can never completely satisfy the requirements for
|
||||
<a
|
||||
href="http://www.sgi.com/tech/stl/ForwardIterator.html">Forward Iterator</a>
|
||||
(or of any concepts that refine Forward Iterator, which includes
|
||||
Random Access Iterator and Bidirectional Iterator) since the <tt>operator*</tt> of the transform
|
||||
iterator always returns by-value.
|
||||
|
||||
|
||||
|
||||
<hr>
|
||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->19 Aug 2001<!--webbot bot="Timestamp" endspan i-checksum="14767" --></p>
|
||||
<p>© Copyright Jeremy Siek 2000. Permission to copy, use,
|
||||
modify, sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided "as is"
|
||||
without express or implied warranty, and with no claim as to its suitability for
|
||||
any purpose.</p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user