mirror of
https://github.com/boostorg/utility.git
synced 2025-10-06 05:50:54 +02:00
Compare commits
20 Commits
svn-branch
...
boost-1.21
Author | SHA1 | Date | |
---|---|---|---|
|
d944c6538f | ||
|
feb370b201 | ||
|
d1b34e64d8 | ||
|
b9a1eead40 | ||
|
1e4bfac98c | ||
|
3bb504fbf3 | ||
|
5029791c90 | ||
|
a1a68f0970 | ||
|
f8543d79eb | ||
|
f353415136 | ||
|
26240403b0 | ||
|
3a39729b58 | ||
|
096c961d9a | ||
|
01fe04a6a2 | ||
|
7ea4014993 | ||
|
d50b374f88 | ||
|
27dfb25570 | ||
|
b5ed77985e | ||
|
61243bd15f | ||
|
368b94d804 |
@@ -34,9 +34,9 @@ specialization or member templates, no benefit will occur from
|
|||||||
using call_traits: the call_traits defined types will always be
|
using call_traits: the call_traits defined types will always be
|
||||||
the same as the existing practice in this case. In addition if
|
the same as the existing practice in this case. In addition if
|
||||||
only member templates and not partial template specialisation is
|
only member templates and not partial template specialisation is
|
||||||
support by the compiler (for example Visual C++ 6) then call_traits
|
support by the compiler (for example Visual C++ 6) then
|
||||||
can not be used with array types (although it can be used to
|
call_traits can not be used with array types (although it can be
|
||||||
solve the reference to reference problem).</p>
|
used to solve the reference to reference problem).</p>
|
||||||
|
|
||||||
<table border="0" cellpadding="7" cellspacing="1" width="797">
|
<table border="0" cellpadding="7" cellspacing="1" width="797">
|
||||||
<tr>
|
<tr>
|
||||||
@@ -79,7 +79,8 @@ solve the reference to reference problem).</p>
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td valign="top" width="17%"><p align="center">const T&<br>
|
<td valign="top" width="17%"><p align="center">const
|
||||||
|
T&<br>
|
||||||
(return value)</p>
|
(return value)</p>
|
||||||
</td>
|
</td>
|
||||||
<td valign="top" width="35%"><p align="center"><code>call_traits<T>::const_reference</code></p>
|
<td valign="top" width="35%"><p align="center"><code>call_traits<T>::const_reference</code></p>
|
||||||
@@ -91,7 +92,8 @@ solve the reference to reference problem).</p>
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td valign="top" width="17%"><p align="center">const T&<br>
|
<td valign="top" width="17%"><p align="center">const
|
||||||
|
T&<br>
|
||||||
(function parameter)</p>
|
(function parameter)</p>
|
||||||
</td>
|
</td>
|
||||||
<td valign="top" width="35%"><p align="center"><code>call_traits<T>::param_type</code></p>
|
<td valign="top" width="35%"><p align="center"><code>call_traits<T>::param_type</code></p>
|
||||||
@@ -332,8 +334,8 @@ possible:</p>
|
|||||||
<p>The following table shows the effect that call_traits has on
|
<p>The following table shows the effect that call_traits has on
|
||||||
various types, the table assumes that the compiler supports
|
various types, the table assumes that the compiler supports
|
||||||
partial specialization: if it doesn't then all types behave in
|
partial specialization: if it doesn't then all types behave in
|
||||||
the same way as the entry for "myclass", and call_traits
|
the same way as the entry for "myclass", and
|
||||||
can not be used with reference or array types.</p>
|
call_traits can not be used with reference or array types.</p>
|
||||||
|
|
||||||
<table border="0" cellpadding="7" cellspacing="1" width="766">
|
<table border="0" cellpadding="7" cellspacing="1" width="766">
|
||||||
<tr>
|
<tr>
|
||||||
@@ -388,7 +390,8 @@ can not be used with reference or array types.</p>
|
|||||||
</td>
|
</td>
|
||||||
<td valign="top" width="17%"><p align="center">int&</p>
|
<td valign="top" width="17%"><p align="center">int&</p>
|
||||||
</td>
|
</td>
|
||||||
<td valign="top" width="17%"><p align="center">const int&</p>
|
<td valign="top" width="17%"><p align="center">const
|
||||||
|
int&</p>
|
||||||
</td>
|
</td>
|
||||||
<td valign="top" width="17%"><p align="center">int const</p>
|
<td valign="top" width="17%"><p align="center">int const</p>
|
||||||
</td>
|
</td>
|
||||||
@@ -420,7 +423,8 @@ can not be used with reference or array types.</p>
|
|||||||
</td>
|
</td>
|
||||||
<td valign="top" width="17%"><p align="center">int&</p>
|
<td valign="top" width="17%"><p align="center">int&</p>
|
||||||
</td>
|
</td>
|
||||||
<td valign="top" width="17%"><p align="center">const int&</p>
|
<td valign="top" width="17%"><p align="center">const
|
||||||
|
int&</p>
|
||||||
</td>
|
</td>
|
||||||
<td valign="top" width="17%"><p align="center">int&</p>
|
<td valign="top" width="17%"><p align="center">int&</p>
|
||||||
</td>
|
</td>
|
||||||
@@ -432,13 +436,17 @@ can not be used with reference or array types.</p>
|
|||||||
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
|
||||||
align="center">const int&</p>
|
align="center">const int&</p>
|
||||||
</td>
|
</td>
|
||||||
<td valign="top" width="17%"><p align="center">const int&</p>
|
<td valign="top" width="17%"><p align="center">const
|
||||||
|
int&</p>
|
||||||
</td>
|
</td>
|
||||||
<td valign="top" width="17%"><p align="center">const int&</p>
|
<td valign="top" width="17%"><p align="center">const
|
||||||
|
int&</p>
|
||||||
</td>
|
</td>
|
||||||
<td valign="top" width="17%"><p align="center">const int&</p>
|
<td valign="top" width="17%"><p align="center">const
|
||||||
|
int&</p>
|
||||||
</td>
|
</td>
|
||||||
<td valign="top" width="17%"><p align="center">const int&</p>
|
<td valign="top" width="17%"><p align="center">const
|
||||||
|
int&</p>
|
||||||
</td>
|
</td>
|
||||||
<td valign="top" width="17%"><p align="center">All
|
<td valign="top" width="17%"><p align="center">All
|
||||||
constant-references.</p>
|
constant-references.</p>
|
||||||
@@ -486,8 +494,8 @@ can not be used with reference or array types.</p>
|
|||||||
|
|
||||||
<p>The following class is a trivial class that stores some type T
|
<p>The following class is a trivial class that stores some type T
|
||||||
by value (see the <a href="call_traits_test.cpp">call_traits_test.cpp</a>
|
by value (see the <a href="call_traits_test.cpp">call_traits_test.cpp</a>
|
||||||
file), the aim is to illustrate how each of the available call_traits
|
file), the aim is to illustrate how each of the available
|
||||||
typedefs may be used:</p>
|
call_traits typedefs may be used:</p>
|
||||||
|
|
||||||
<pre>template <class T>
|
<pre>template <class T>
|
||||||
struct contained
|
struct contained
|
||||||
@@ -523,14 +531,14 @@ problem):</h4>
|
|||||||
|
|
||||||
<pre>template <class Operation>
|
<pre>template <class Operation>
|
||||||
class binder1st :
|
class binder1st :
|
||||||
public unary_function<Operation::second_argument_type, Operation::result_type>
|
public unary_function<typename Operation::second_argument_type, typename Operation::result_type>
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
Operation op;
|
Operation op;
|
||||||
Operation::first_argument_type value;
|
typename Operation::first_argument_type value;
|
||||||
public:
|
public:
|
||||||
binder1st(const Operation& x, const Operation::first_argument_type& y);
|
binder1st(const Operation& x, const typename Operation::first_argument_type& y);
|
||||||
Operation::result_type operator()(const Operation::second_argument_type& x) const;
|
typename Operation::result_type operator()(const typename Operation::second_argument_type& x) const;
|
||||||
}; </pre>
|
}; </pre>
|
||||||
|
|
||||||
<p>Now consider what happens in the relatively common case that
|
<p>Now consider what happens in the relatively common case that
|
||||||
@@ -541,7 +549,7 @@ reference to a reference as an argument, and that is not
|
|||||||
currently legal. The solution here is to modify <code>operator()</code>
|
currently legal. The solution here is to modify <code>operator()</code>
|
||||||
to use call_traits:</p>
|
to use call_traits:</p>
|
||||||
|
|
||||||
<pre>Operation::result_type operator()(call_traits<Operation::second_argument_type>::param_type x) const;</pre>
|
<pre>typename Operation::result_type operator()(typename call_traits<typename Operation::second_argument_type>::param_type x) const;</pre>
|
||||||
|
|
||||||
<p>Now in the case that <code>Operation::second_argument_type</code>
|
<p>Now in the case that <code>Operation::second_argument_type</code>
|
||||||
is a reference type, the argument is passed as a reference, and
|
is a reference type, the argument is passed as a reference, and
|
||||||
@@ -575,9 +583,9 @@ std::pair<
|
|||||||
degraded to pointers if the deduced types are arrays, similar
|
degraded to pointers if the deduced types are arrays, similar
|
||||||
situations occur in the standard binders and adapters: in
|
situations occur in the standard binders and adapters: in
|
||||||
principle in any function that "wraps" a temporary
|
principle in any function that "wraps" a temporary
|
||||||
whose type is deduced. Note that the function arguments to make_pair
|
whose type is deduced. Note that the function arguments to
|
||||||
are not expressed in terms of call_traits: doing so would prevent
|
make_pair are not expressed in terms of call_traits: doing so
|
||||||
template argument deduction from functioning.</p>
|
would prevent template argument deduction from functioning.</p>
|
||||||
|
|
||||||
<h4><a name="ex4"></a>Example 4 (optimising fill):</h4>
|
<h4><a name="ex4"></a>Example 4 (optimising fill):</h4>
|
||||||
|
|
||||||
@@ -666,10 +674,10 @@ be any worse than existing practice.</p>
|
|||||||
<p>Pointers follow the same rational as small built-in types.</p>
|
<p>Pointers follow the same rational as small built-in types.</p>
|
||||||
|
|
||||||
<p>For reference types the rational follows <a href="#refs">Example
|
<p>For reference types the rational follows <a href="#refs">Example
|
||||||
2</a> - references to references are not allowed, so the call_traits
|
2</a> - references to references are not allowed, so the
|
||||||
members must be defined such that these problems do not occur.
|
call_traits members must be defined such that these problems do
|
||||||
There is a proposal to modify the language such that "a
|
not occur. There is a proposal to modify the language such that
|
||||||
reference to a reference is a reference" (issue #106,
|
"a reference to a reference is a reference" (issue #106,
|
||||||
submitted by Bjarne Stroustrup), call_traits<T>::value_type
|
submitted by Bjarne Stroustrup), call_traits<T>::value_type
|
||||||
and call_traits<T>::param_type both provide the same effect
|
and call_traits<T>::param_type both provide the same effect
|
||||||
as that proposal, without the need for a language change (in
|
as that proposal, without the need for a language change (in
|
||||||
@@ -687,11 +695,11 @@ struct A
|
|||||||
void foo(T t);
|
void foo(T t);
|
||||||
};</pre>
|
};</pre>
|
||||||
|
|
||||||
<p><font face="Times New Roman">In this case if we instantiate A<int[2]>
|
<p><font face="Times New Roman">In this case if we instantiate
|
||||||
then the declared type of the parameter passed to member function
|
A<int[2]> then the declared type of the parameter passed to
|
||||||
foo is int[2], but it's actual type is const int*, if we try to
|
member function foo is int[2], but it's actual type is const int*,
|
||||||
use the type T within the function body, then there is a strong
|
if we try to use the type T within the function body, then there
|
||||||
likelyhood that our code will not compile:</font></p>
|
is a strong likelyhood that our code will not compile:</font></p>
|
||||||
|
|
||||||
<pre>template <class T>
|
<pre>template <class T>
|
||||||
void A<T>::foo(T t)
|
void A<T>::foo(T t)
|
||||||
@@ -706,13 +714,13 @@ declared type:</p>
|
|||||||
<pre>template <class T>
|
<pre>template <class T>
|
||||||
struct A
|
struct A
|
||||||
{
|
{
|
||||||
void foo(call_traits<T>::value_type t);
|
void foo(typename call_traits<T>::value_type t);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void A<T>::foo(call_traits<T>::value_type t)
|
void A<T>::foo(typename call_traits<T>::value_type t)
|
||||||
{
|
{
|
||||||
call_traits<T>::value_type dup(t); // OK even if T is an array type.
|
typename call_traits<T>::value_type dup(t); // OK even if T is an array type.
|
||||||
}</pre>
|
}</pre>
|
||||||
|
|
||||||
<p>For value_type (return by value), again only a pointer may be
|
<p>For value_type (return by value), again only a pointer may be
|
||||||
|
@@ -117,13 +117,14 @@ void call_traits_checker<T>::operator()(param_type p)
|
|||||||
assert(t == c.value());
|
assert(t == c.value());
|
||||||
assert(t == c.get());
|
assert(t == c.get());
|
||||||
assert(t == c.const_get());
|
assert(t == c.const_get());
|
||||||
|
#ifndef __ICL
|
||||||
//cout << "typeof contained<" << typeid(T).name() << ">::v_ is: " << typeid(&contained<T>::v_).name() << endl;
|
//cout << "typeof contained<" << typeid(T).name() << ">::v_ is: " << typeid(&contained<T>::v_).name() << endl;
|
||||||
cout << "typeof contained<" << typeid(T).name() << ">::value() is: " << typeid(&contained<T>::value).name() << endl;
|
cout << "typeof contained<" << typeid(T).name() << ">::value() is: " << typeid(&contained<T>::value).name() << endl;
|
||||||
cout << "typeof contained<" << typeid(T).name() << ">::get() is: " << typeid(&contained<T>::get).name() << endl;
|
cout << "typeof contained<" << typeid(T).name() << ">::get() is: " << typeid(&contained<T>::get).name() << endl;
|
||||||
cout << "typeof contained<" << typeid(T).name() << ">::const_get() is: " << typeid(&contained<T>::const_get).name() << endl;
|
cout << "typeof contained<" << typeid(T).name() << ">::const_get() is: " << typeid(&contained<T>::const_get).name() << endl;
|
||||||
cout << "typeof contained<" << typeid(T).name() << ">::call() is: " << typeid(&contained<T>::call).name() << endl;
|
cout << "typeof contained<" << typeid(T).name() << ">::call() is: " << typeid(&contained<T>::call).name() << endl;
|
||||||
cout << endl;
|
cout << endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
@@ -373,3 +374,4 @@ unsigned int expected_failures = 0;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -96,11 +96,11 @@ int main(int argc, char *argv[ ])
|
|||||||
cp7.first();
|
cp7.first();
|
||||||
double* pd = cp7.second();
|
double* pd = cp7.second();
|
||||||
#endif
|
#endif
|
||||||
value_test(true, (sizeof(compressed_pair<empty_UDT, int>) < sizeof(std::pair<empty_UDT, int>)))
|
soft_value_test(true, (sizeof(compressed_pair<empty_UDT, int>) < sizeof(std::pair<empty_UDT, int>)))
|
||||||
value_test(true, (sizeof(compressed_pair<int, empty_UDT>) < sizeof(std::pair<int, empty_UDT>)))
|
soft_value_test(true, (sizeof(compressed_pair<int, empty_UDT>) < sizeof(std::pair<int, empty_UDT>)))
|
||||||
value_test(true, (sizeof(compressed_pair<empty_UDT, empty_UDT>) < sizeof(std::pair<empty_UDT, empty_UDT>)))
|
soft_value_test(true, (sizeof(compressed_pair<empty_UDT, empty_UDT>) < sizeof(std::pair<empty_UDT, empty_UDT>)))
|
||||||
value_test(true, (sizeof(compressed_pair<empty_UDT, empty_POD_UDT>) < sizeof(std::pair<empty_UDT, empty_POD_UDT>)))
|
soft_value_test(true, (sizeof(compressed_pair<empty_UDT, empty_POD_UDT>) < sizeof(std::pair<empty_UDT, empty_POD_UDT>)))
|
||||||
value_test(true, (sizeof(compressed_pair<empty_UDT, compressed_pair<empty_POD_UDT, int> >) < sizeof(std::pair<empty_UDT, std::pair<empty_POD_UDT, int> >)))
|
soft_value_test(true, (sizeof(compressed_pair<empty_UDT, compressed_pair<empty_POD_UDT, int> >) < sizeof(std::pair<empty_UDT, std::pair<empty_POD_UDT, int> >)))
|
||||||
|
|
||||||
return check_result(argc, argv);
|
return check_result(argc, argv);
|
||||||
}
|
}
|
||||||
@@ -147,15 +147,7 @@ template compressed_pair<double, int[2]>::compressed_pair();
|
|||||||
#endif // __MWERKS__
|
#endif // __MWERKS__
|
||||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
|
||||||
// can't handle both types empty:
|
|
||||||
unsigned int expected_failures = 4;
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
// no zero sized base classes:
|
|
||||||
unsigned int expected_failures = 4;
|
|
||||||
#else
|
|
||||||
unsigned int expected_failures = 0;
|
unsigned int expected_failures = 0;
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -282,7 +282,7 @@ template <class Incrementable>
|
|||||||
struct counting_iterator_traits
|
struct counting_iterator_traits
|
||||||
{
|
{
|
||||||
if (numeric_limits<Incrementable>::is_specialized) {
|
if (numeric_limits<Incrementable>::is_specialized) {
|
||||||
if (!numeric_limits<Incrementable>::is_integral)
|
if (!numeric_limits<Incrementable>::is_integer)
|
||||||
COMPILE_TIME_ERROR;
|
COMPILE_TIME_ERROR;
|
||||||
|
|
||||||
if (!numeric_limits<Incrementable>::is_bounded
|
if (!numeric_limits<Incrementable>::is_bounded
|
||||||
@@ -308,7 +308,7 @@ implementation, the <tt>difference_type</tt> for any variable-length signed
|
|||||||
integer type <tt>T</tt> is <tt>T</tt> itself.
|
integer type <tt>T</tt> is <tt>T</tt> itself.
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->15 Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14373" --></p>
|
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->28 Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14390" --></p>
|
||||||
<p><EFBFBD> Copyright Jeremy Siek 2000. Permission to copy, use,
|
<p><EFBFBD> Copyright Jeremy Siek 2000. Permission to copy, use,
|
||||||
modify, sell and distribute this document is granted provided this copyright
|
modify, sell and distribute this document is granted provided this copyright
|
||||||
notice appears in all copies. This document is provided "as is"
|
notice appears in all copies. This document is provided "as is"
|
||||||
|
@@ -168,8 +168,8 @@ this parameter is the appropriate type.<br>
|
|||||||
|
|
||||||
The filter iterator adaptor (the type
|
The filter iterator adaptor (the type
|
||||||
<tt>filter_iterator_generator<...>::type</tt>) may be a model of <a
|
<tt>filter_iterator_generator<...>::type</tt>) may be a model of <a
|
||||||
href="www.sgi.com/tech/stl/InputIterator.html">InputIterator</a> or <a
|
href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a> or <a
|
||||||
href="www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>
|
href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>
|
||||||
depending on the adapted iterator type.
|
depending on the adapted iterator type.
|
||||||
|
|
||||||
|
|
||||||
@@ -261,7 +261,7 @@ default).
|
|||||||
|
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->10 Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14373" --></p>
|
<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><EFBFBD> Copyright Jeremy Siek 2000. Permission to copy, use,
|
<p><EFBFBD> Copyright Jeremy Siek 2000. Permission to copy, use,
|
||||||
modify, sell and distribute this document is granted provided this copyright
|
modify, sell and distribute this document is granted provided this copyright
|
||||||
notice appears in all copies. This document is provided "as is"
|
notice appears in all copies. This document is provided "as is"
|
||||||
|
41
fun_out_iter_example.cpp
Normal file
41
fun_out_iter_example.cpp
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
// (C) Copyright Jeremy Siek 2001. Permission to copy, use, modify,
|
||||||
|
// sell and distribute this software is granted provided this
|
||||||
|
// copyright notice appears in all copies. This software is provided
|
||||||
|
// "as is" without express or implied warranty, and with no claim as
|
||||||
|
// to its suitability for any purpose.
|
||||||
|
|
||||||
|
// Revision History:
|
||||||
|
|
||||||
|
// 27 Feb 2001 Jeremy Siek
|
||||||
|
// Initial checkin.
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
169
function_output_iterator.htm
Normal file
169
function_output_iterator.htm
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
<!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>
|
@@ -422,8 +422,7 @@ a,b,c,d,e,f,g,
|
|||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<p>Revised
|
<p>Revised
|
||||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->10
|
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->28 Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14390" -->
|
||||||
Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14373" -->
|
|
||||||
|
|
||||||
|
|
||||||
<p>© Copyright Jeremy Siek and David Abrahams 2001. Permission to
|
<p>© Copyright Jeremy Siek and David Abrahams 2001. Permission to
|
||||||
|
151
indirect_iterator_test.cpp
Normal file
151
indirect_iterator_test.cpp
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
|
||||||
|
// sell and distribute this software is granted provided this
|
||||||
|
// copyright notice appears in all copies. This software is provided
|
||||||
|
// "as is" without express or implied warranty, and with no claim as
|
||||||
|
// to its suitability for any purpose.
|
||||||
|
|
||||||
|
// Revision History
|
||||||
|
// 08 Mar 2001 Jeremy Siek
|
||||||
|
// Moved test of indirect iterator into its own file. It to
|
||||||
|
// to be in iterator_adaptor_test.cpp.
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <boost/iterator_adaptors.hpp>
|
||||||
|
#include <boost/pending/iterator_tests.hpp>
|
||||||
|
#include <boost/concept_archetype.hpp>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <deque>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
struct my_iterator_tag : public std::random_access_iterator_tag { };
|
||||||
|
|
||||||
|
using boost::dummyT;
|
||||||
|
|
||||||
|
typedef std::deque<int> storage;
|
||||||
|
typedef std::deque<int*> pointer_deque;
|
||||||
|
typedef std::set<storage::iterator> iterator_set;
|
||||||
|
|
||||||
|
void more_indirect_iterator_tests()
|
||||||
|
{
|
||||||
|
// For some reason all heck breaks loose in the compiler under these conditions.
|
||||||
|
#if !defined(BOOST_MSVC) || !defined(__STL_DEBUG)
|
||||||
|
storage store(1000);
|
||||||
|
std::generate(store.begin(), store.end(), rand);
|
||||||
|
|
||||||
|
pointer_deque ptr_deque;
|
||||||
|
iterator_set iter_set;
|
||||||
|
|
||||||
|
for (storage::iterator p = store.begin(); p != store.end(); ++p)
|
||||||
|
{
|
||||||
|
ptr_deque.push_back(&*p);
|
||||||
|
iter_set.insert(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef boost::indirect_iterator_pair_generator<
|
||||||
|
pointer_deque::iterator
|
||||||
|
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
, int
|
||||||
|
#endif
|
||||||
|
> IndirectDeque;
|
||||||
|
|
||||||
|
IndirectDeque::iterator db(ptr_deque.begin());
|
||||||
|
IndirectDeque::iterator de(ptr_deque.end());
|
||||||
|
assert(static_cast<std::size_t>(de - db) == store.size());
|
||||||
|
assert(db + store.size() == de);
|
||||||
|
IndirectDeque::const_iterator dci(db);
|
||||||
|
assert(db == dci);
|
||||||
|
assert(dci == db);
|
||||||
|
assert(dci != de);
|
||||||
|
assert(dci < de);
|
||||||
|
assert(dci <= de);
|
||||||
|
assert(de >= dci);
|
||||||
|
assert(de > dci);
|
||||||
|
dci = de;
|
||||||
|
assert(dci == de);
|
||||||
|
|
||||||
|
boost::random_access_iterator_test(db + 1, store.size() - 1, boost::next(store.begin()));
|
||||||
|
|
||||||
|
*db = 999;
|
||||||
|
assert(store.front() == 999);
|
||||||
|
|
||||||
|
// Borland C++ is getting very confused about the typedef's here
|
||||||
|
|
||||||
|
typedef boost::indirect_iterator_generator<
|
||||||
|
iterator_set::iterator
|
||||||
|
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
, int
|
||||||
|
#endif
|
||||||
|
>::type indirect_set_iterator;
|
||||||
|
|
||||||
|
typedef boost::indirect_iterator_generator<
|
||||||
|
iterator_set::iterator,
|
||||||
|
const int
|
||||||
|
>::type const_indirect_set_iterator;
|
||||||
|
|
||||||
|
indirect_set_iterator sb(iter_set.begin());
|
||||||
|
indirect_set_iterator se(iter_set.end());
|
||||||
|
const_indirect_set_iterator sci(iter_set.begin());
|
||||||
|
assert(sci == sb);
|
||||||
|
assert(sci != se);
|
||||||
|
sci = se;
|
||||||
|
assert(sci == se);
|
||||||
|
|
||||||
|
*boost::prior(se) = 888;
|
||||||
|
assert(store.back() == 888);
|
||||||
|
assert(std::equal(sb, se, store.begin()));
|
||||||
|
|
||||||
|
boost::bidirectional_iterator_test(boost::next(sb), store[1], store[2]);
|
||||||
|
assert(std::equal(db, de, store.begin()));
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
dummyT array[] = { dummyT(0), dummyT(1), dummyT(2),
|
||||||
|
dummyT(3), dummyT(4), dummyT(5) };
|
||||||
|
const int N = sizeof(array)/sizeof(dummyT);
|
||||||
|
|
||||||
|
// Test indirect_iterator_generator
|
||||||
|
{
|
||||||
|
dummyT* ptr[N];
|
||||||
|
for (int k = 0; k < N; ++k)
|
||||||
|
ptr[k] = array + k;
|
||||||
|
|
||||||
|
typedef boost::indirect_iterator_generator<dummyT**
|
||||||
|
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
, dummyT
|
||||||
|
#endif
|
||||||
|
>::type indirect_iterator;
|
||||||
|
|
||||||
|
typedef boost::indirect_iterator_generator<dummyT**, const dummyT>::type const_indirect_iterator;
|
||||||
|
|
||||||
|
indirect_iterator i(ptr);
|
||||||
|
boost::random_access_iterator_test(i, N, array);
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
boost::random_access_iterator_test(boost::make_indirect_iterator(ptr), N, array);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// check operator->
|
||||||
|
assert((*i).m_x == i->foo());
|
||||||
|
|
||||||
|
const_indirect_iterator j(ptr);
|
||||||
|
boost::random_access_iterator_test(j, N, array);
|
||||||
|
|
||||||
|
dummyT*const* const_ptr = ptr;
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
boost::random_access_iterator_test(boost::make_indirect_iterator(const_ptr), N, array);
|
||||||
|
#endif
|
||||||
|
boost::const_nonconst_iterator_test(i, ++j);
|
||||||
|
|
||||||
|
more_indirect_iterator_tests();
|
||||||
|
}
|
||||||
|
std::cout << "test successful " << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
61
iter_traits_gen_test.cpp
Normal file
61
iter_traits_gen_test.cpp
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
|
||||||
|
// sell and distribute this software is granted provided this
|
||||||
|
// copyright notice appears in all copies. This software is provided
|
||||||
|
// "as is" without express or implied warranty, and with no claim as
|
||||||
|
// to its suitability for any purpose.
|
||||||
|
|
||||||
|
// 8 Mar 2001 Jeremy Siek
|
||||||
|
// Initial checkin.
|
||||||
|
|
||||||
|
#include <boost/iterator_adaptors.hpp>
|
||||||
|
#include <boost/pending/iterator_tests.hpp>
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
|
||||||
|
class bar { };
|
||||||
|
void foo(bar) { }
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
using boost::dummyT;
|
||||||
|
dummyT array[] = { dummyT(0), dummyT(1), dummyT(2),
|
||||||
|
dummyT(3), dummyT(4), dummyT(5) };
|
||||||
|
typedef boost::iterator_adaptor<dummyT*,
|
||||||
|
boost::default_iterator_policies, dummyT> my_iter;
|
||||||
|
my_iter mi(array);
|
||||||
|
|
||||||
|
{
|
||||||
|
typedef boost::iterator_adaptor<my_iter, boost::default_iterator_policies,
|
||||||
|
boost::iterator_traits_generator
|
||||||
|
::reference<dummyT>
|
||||||
|
::iterator_category<std::input_iterator_tag> > iter_type;
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<iter_type::iterator_category*,
|
||||||
|
std::input_iterator_tag*>::value));
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT(( ! boost::is_convertible<iter_type::iterator_category*,
|
||||||
|
std::forward_iterator_tag*>::value));
|
||||||
|
|
||||||
|
iter_type i(mi);
|
||||||
|
boost::input_iterator_test(i, dummyT(0), dummyT(1));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
typedef boost::iterator_adaptor<dummyT*,
|
||||||
|
boost::default_iterator_policies,
|
||||||
|
boost::iterator_traits_generator
|
||||||
|
::value_type<dummyT>
|
||||||
|
::reference<const dummyT&>
|
||||||
|
::pointer<const dummyT*>
|
||||||
|
::iterator_category<std::forward_iterator_tag>
|
||||||
|
::difference_type<std::ptrdiff_t> > adaptor_type;
|
||||||
|
|
||||||
|
adaptor_type i(array);
|
||||||
|
|
||||||
|
boost::input_iterator_test(i, dummyT(0), dummyT(1));
|
||||||
|
int zero = 0;
|
||||||
|
if (zero) // don't do this, just make sure it compiles
|
||||||
|
assert((*i).m_x == i->foo());
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@@ -1,4 +1,4 @@
|
|||||||
// Demonstrate and test boost/operators.hpp on std::iterators -------------//
|
// Test boost/iterator_adaptors.hpp
|
||||||
|
|
||||||
// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
|
// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
|
||||||
// sell and distribute this software is granted provided this
|
// sell and distribute this software is granted provided this
|
||||||
@@ -9,6 +9,8 @@
|
|||||||
// See http://www.boost.org for most recent version including documentation.
|
// See http://www.boost.org for most recent version including documentation.
|
||||||
|
|
||||||
// Revision History
|
// Revision History
|
||||||
|
// 08 Mar 01 Moved indirect and transform tests to separate files.
|
||||||
|
// (Jeremy Siek)
|
||||||
// 19 Feb 01 Take adavantage of improved iterator_traits to do more tests
|
// 19 Feb 01 Take adavantage of improved iterator_traits to do more tests
|
||||||
// on MSVC. Hack around an MSVC-with-STLport internal compiler
|
// on MSVC. Hack around an MSVC-with-STLport internal compiler
|
||||||
// error. (David Abrahams)
|
// error. (David Abrahams)
|
||||||
@@ -59,28 +61,6 @@ struct my_iterator_tag : public std::random_access_iterator_tag { };
|
|||||||
|
|
||||||
using boost::dummyT;
|
using boost::dummyT;
|
||||||
|
|
||||||
struct my_iter_traits {
|
|
||||||
typedef dummyT value_type;
|
|
||||||
typedef dummyT* pointer;
|
|
||||||
typedef dummyT& reference;
|
|
||||||
typedef my_iterator_tag iterator_category;
|
|
||||||
typedef std::ptrdiff_t difference_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct my_const_iter_traits {
|
|
||||||
typedef dummyT value_type;
|
|
||||||
typedef const dummyT* pointer;
|
|
||||||
typedef const dummyT& reference;
|
|
||||||
typedef my_iterator_tag iterator_category;
|
|
||||||
typedef std::ptrdiff_t difference_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef boost::iterator_adaptor<dummyT*,
|
|
||||||
boost::default_iterator_policies, dummyT> my_iterator;
|
|
||||||
|
|
||||||
typedef boost::iterator_adaptor<const dummyT*,
|
|
||||||
boost::default_iterator_policies, const dummyT> const_my_iterator;
|
|
||||||
|
|
||||||
|
|
||||||
struct mult_functor {
|
struct mult_functor {
|
||||||
typedef int result_type;
|
typedef int result_type;
|
||||||
@@ -117,78 +97,6 @@ typedef std::deque<int> storage;
|
|||||||
typedef std::deque<int*> pointer_deque;
|
typedef std::deque<int*> pointer_deque;
|
||||||
typedef std::set<storage::iterator> iterator_set;
|
typedef std::set<storage::iterator> iterator_set;
|
||||||
|
|
||||||
void more_indirect_iterator_tests()
|
|
||||||
{
|
|
||||||
// For some reason all heck breaks loose in the compiler under these conditions.
|
|
||||||
#if !defined(BOOST_MSVC) || !defined(__STL_DEBUG)
|
|
||||||
storage store(1000);
|
|
||||||
std::generate(store.begin(), store.end(), rand);
|
|
||||||
|
|
||||||
pointer_deque ptr_deque;
|
|
||||||
iterator_set iter_set;
|
|
||||||
|
|
||||||
for (storage::iterator p = store.begin(); p != store.end(); ++p)
|
|
||||||
{
|
|
||||||
ptr_deque.push_back(&*p);
|
|
||||||
iter_set.insert(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef boost::indirect_iterator_pair_generator<
|
|
||||||
pointer_deque::iterator
|
|
||||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
|
||||||
, int
|
|
||||||
#endif
|
|
||||||
> IndirectDeque;
|
|
||||||
|
|
||||||
IndirectDeque::iterator db(ptr_deque.begin());
|
|
||||||
IndirectDeque::iterator de(ptr_deque.end());
|
|
||||||
assert(static_cast<std::size_t>(de - db) == store.size());
|
|
||||||
assert(db + store.size() == de);
|
|
||||||
IndirectDeque::const_iterator dci(db);
|
|
||||||
assert(db == dci);
|
|
||||||
assert(dci == db);
|
|
||||||
assert(dci != de);
|
|
||||||
assert(dci < de);
|
|
||||||
assert(dci <= de);
|
|
||||||
assert(de >= dci);
|
|
||||||
assert(de > dci);
|
|
||||||
dci = de;
|
|
||||||
assert(dci == de);
|
|
||||||
|
|
||||||
boost::random_access_iterator_test(db + 1, store.size() - 1, boost::next(store.begin()));
|
|
||||||
|
|
||||||
*db = 999;
|
|
||||||
assert(store.front() == 999);
|
|
||||||
|
|
||||||
typedef boost::indirect_iterator_generator<
|
|
||||||
iterator_set::iterator
|
|
||||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
|
||||||
, int
|
|
||||||
#endif
|
|
||||||
>::type indirect_set_iterator;
|
|
||||||
|
|
||||||
typedef boost::indirect_iterator_generator<
|
|
||||||
iterator_set::iterator,
|
|
||||||
const int
|
|
||||||
>::type const_indirect_set_iterator;
|
|
||||||
|
|
||||||
indirect_set_iterator sb(iter_set.begin());
|
|
||||||
indirect_set_iterator se(iter_set.end());
|
|
||||||
const_indirect_set_iterator sci(iter_set.begin());
|
|
||||||
assert(sci == sb);
|
|
||||||
assert(sci != se);
|
|
||||||
sci = se;
|
|
||||||
assert(sci == se);
|
|
||||||
|
|
||||||
*boost::prior(se) = 888;
|
|
||||||
assert(store.back() == 888);
|
|
||||||
assert(std::equal(sb, se, store.begin()));
|
|
||||||
|
|
||||||
boost::bidirectional_iterator_test(boost::next(sb), store[1], store[2]);
|
|
||||||
assert(std::equal(db, de, store.begin()));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
@@ -210,67 +118,14 @@ main()
|
|||||||
|
|
||||||
// Test the iterator_adaptor
|
// Test the iterator_adaptor
|
||||||
{
|
{
|
||||||
my_iterator i(array);
|
boost::iterator_adaptor<dummyT*, boost::default_iterator_policies, dummyT> i(array);
|
||||||
boost::random_access_iterator_test(i, N, array);
|
boost::random_access_iterator_test(i, N, array);
|
||||||
|
|
||||||
const_my_iterator j(array);
|
boost::iterator_adaptor<const dummyT*, boost::default_iterator_policies, const dummyT> j(array);
|
||||||
boost::random_access_iterator_test(j, N, array);
|
boost::random_access_iterator_test(j, N, array);
|
||||||
boost::const_nonconst_iterator_test(i, ++j);
|
boost::const_nonconst_iterator_test(i, ++j);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test transform_iterator
|
|
||||||
{
|
|
||||||
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::transform_iterator_generator<mult_functor, int*>::type
|
|
||||||
i(y, mult_functor(2));
|
|
||||||
boost::input_iterator_test(i, x[0], x[1]);
|
|
||||||
boost::input_iterator_test(boost::make_transform_iterator(&y[0], mult_functor(2)), x[0], x[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test indirect_iterator_generator
|
|
||||||
{
|
|
||||||
dummyT* ptr[N];
|
|
||||||
for (int k = 0; k < N; ++k)
|
|
||||||
ptr[k] = array + k;
|
|
||||||
|
|
||||||
typedef boost::indirect_iterator_generator<dummyT**
|
|
||||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
|
||||||
, dummyT
|
|
||||||
#endif
|
|
||||||
>::type indirect_iterator;
|
|
||||||
|
|
||||||
typedef boost::indirect_iterator_generator<dummyT**, const dummyT>::type const_indirect_iterator;
|
|
||||||
|
|
||||||
indirect_iterator i(ptr);
|
|
||||||
boost::random_access_iterator_test(i, N, array);
|
|
||||||
|
|
||||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
|
||||||
boost::random_access_iterator_test(boost::make_indirect_iterator(ptr), N, array);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// check operator->
|
|
||||||
assert((*i).m_x == i->foo());
|
|
||||||
|
|
||||||
const_indirect_iterator j(ptr);
|
|
||||||
boost::random_access_iterator_test(j, N, array);
|
|
||||||
|
|
||||||
dummyT*const* const_ptr = ptr;
|
|
||||||
|
|
||||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
|
||||||
boost::random_access_iterator_test(boost::make_indirect_iterator(const_ptr), N, array);
|
|
||||||
#endif
|
|
||||||
boost::const_nonconst_iterator_test(i, ++j);
|
|
||||||
|
|
||||||
more_indirect_iterator_tests();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test projection_iterator_pair_generator
|
// Test projection_iterator_pair_generator
|
||||||
{
|
{
|
||||||
typedef std::pair<dummyT,dummyT> Pair;
|
typedef std::pair<dummyT,dummyT> Pair;
|
||||||
@@ -376,23 +231,33 @@ main()
|
|||||||
|
|
||||||
// Test filter iterator
|
// Test filter iterator
|
||||||
{
|
{
|
||||||
// Using typedefs for filter_gen::type and filter_gen::policies_type
|
// Using typedefs for filter_gen::type confused Borland terribly.
|
||||||
// confused Borland terribly.
|
|
||||||
typedef boost::detail::non_bidirectional_category<dummyT*>::type category;
|
typedef boost::detail::non_bidirectional_category<dummyT*>::type category;
|
||||||
|
|
||||||
typedef ::boost::filter_iterator_generator<one_or_four, dummyT*
|
typedef boost::filter_iterator_generator<one_or_four, dummyT*
|
||||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
, dummyT
|
, dummyT
|
||||||
#endif
|
#endif
|
||||||
>::type filter_iter;
|
>::type filter_iter;
|
||||||
|
|
||||||
|
#if defined(__BORLANDC__)
|
||||||
|
// Borland is choking on accessing the policies_type explicitly
|
||||||
|
// from the filter_iter.
|
||||||
|
boost::forward_iterator_test(make_filter_iterator(array, array+N,
|
||||||
|
one_or_four()),
|
||||||
|
dummyT(1), dummyT(4));
|
||||||
|
#else
|
||||||
filter_iter i(array, filter_iter::policies_type(one_or_four(), array + N));
|
filter_iter i(array, filter_iter::policies_type(one_or_four(), array + N));
|
||||||
boost::forward_iterator_test(i, dummyT(1), dummyT(4));
|
boost::forward_iterator_test(i, dummyT(1), dummyT(4));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(__BORLANDC__)
|
||||||
|
//
|
||||||
enum { is_forward = boost::is_same<
|
enum { is_forward = boost::is_same<
|
||||||
filter_iter::iterator_category,
|
filter_iter::iterator_category,
|
||||||
std::forward_iterator_tag>::value };
|
std::forward_iterator_tag>::value };
|
||||||
BOOST_STATIC_ASSERT(is_forward);
|
BOOST_STATIC_ASSERT(is_forward);
|
||||||
|
#endif
|
||||||
|
|
||||||
// On compilers not supporting partial specialization, we can do more type
|
// On compilers not supporting partial specialization, we can do more type
|
||||||
// deduction with deque iterators than with pointers... unless the library
|
// deduction with deque iterators than with pointers... unless the library
|
||||||
@@ -433,12 +298,24 @@ main()
|
|||||||
// check operator-> with a forward iterator
|
// check operator-> with a forward iterator
|
||||||
{
|
{
|
||||||
boost::forward_iterator_archetype<dummyT> forward_iter;
|
boost::forward_iterator_archetype<dummyT> forward_iter;
|
||||||
|
#if defined(__BORLANDC__)
|
||||||
typedef boost::iterator_adaptor<boost::forward_iterator_archetype<dummyT>,
|
typedef boost::iterator_adaptor<boost::forward_iterator_archetype<dummyT>,
|
||||||
boost::default_iterator_policies,
|
boost::default_iterator_policies,
|
||||||
dummyT, const dummyT&, const dummyT*,
|
dummyT, const dummyT&, const dummyT*,
|
||||||
std::forward_iterator_tag, std::ptrdiff_t> adaptor_type;
|
std::forward_iterator_tag, std::ptrdiff_t> adaptor_type;
|
||||||
|
#else
|
||||||
|
typedef boost::iterator_adaptor<boost::forward_iterator_archetype<dummyT>,
|
||||||
|
boost::default_iterator_policies,
|
||||||
|
boost::iterator_traits_generator
|
||||||
|
::value_type<dummyT>
|
||||||
|
::reference<const dummyT&>
|
||||||
|
::pointer<const dummyT*>
|
||||||
|
::iterator_category<std::forward_iterator_tag>
|
||||||
|
::difference_type<std::ptrdiff_t> > adaptor_type;
|
||||||
|
#endif
|
||||||
adaptor_type i(forward_iter);
|
adaptor_type i(forward_iter);
|
||||||
if (0) // don't do this, just make sure it compiles
|
int zero = 0;
|
||||||
|
if (zero) // don't do this, just make sure it compiles
|
||||||
assert((*i).m_x == i->foo());
|
assert((*i).m_x == i->foo());
|
||||||
}
|
}
|
||||||
// check operator-> with an input iterator
|
// check operator-> with an input iterator
|
||||||
@@ -449,10 +326,10 @@ main()
|
|||||||
dummyT, const dummyT&, const dummyT*,
|
dummyT, const dummyT&, const dummyT*,
|
||||||
std::input_iterator_tag, std::ptrdiff_t> adaptor_type;
|
std::input_iterator_tag, std::ptrdiff_t> adaptor_type;
|
||||||
adaptor_type i(input_iter);
|
adaptor_type i(input_iter);
|
||||||
if (0) // don't do this, just make sure it compiles
|
int zero = 0;
|
||||||
|
if (zero) // don't do this, just make sure it compiles
|
||||||
assert((*i).m_x == i->foo());
|
assert((*i).m_x == i->foo());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "test successful " << std::endl;
|
std::cout << "test successful " << std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -44,6 +44,8 @@
|
|||||||
|
|
||||||
<li><a href="#template_parameters">Template Parameters</a>
|
<li><a href="#template_parameters">Template Parameters</a>
|
||||||
|
|
||||||
|
<li><a href="#named_template_parameters">Named Template Parameters</a>
|
||||||
|
|
||||||
<li><a href="#policies">The Policies Class</a>
|
<li><a href="#policies">The Policies Class</a>
|
||||||
|
|
||||||
<li><a href="#additional_members">Additional Class Members</a>
|
<li><a href="#additional_members">Additional Class Members</a>
|
||||||
@@ -63,7 +65,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
Specialized Iterator Adaptors
|
<a name="specialized_adaptors">Specialized Iterator Adaptors</a>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="indirect_iterator.htm">Indirect Iterator Adaptor</a>
|
<li><a href="indirect_iterator.htm">Indirect Iterator Adaptor</a>
|
||||||
@@ -84,6 +86,11 @@
|
|||||||
"../../boost/counting_iterator.hpp">boost/counting_iterator.hpp</a></tt><br>
|
"../../boost/counting_iterator.hpp">boost/counting_iterator.hpp</a></tt><br>
|
||||||
|
|
||||||
<a href="counting_iterator.htm">Counting Iterator Adaptor</a>
|
<a href="counting_iterator.htm">Counting Iterator Adaptor</a>
|
||||||
|
|
||||||
|
<li>Header <tt><a href=
|
||||||
|
"../../boost/function_output_iterator.hpp">boost/function_output_iterator.hpp</a></tt><br>
|
||||||
|
|
||||||
|
<a href="function_output_iterator.htm">Function Output Iterator Adaptor</a>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p><b><a href="http://www.boost.org/people/dave_abrahams.htm">Dave
|
<p><b><a href="http://www.boost.org/people/dave_abrahams.htm">Dave
|
||||||
@@ -98,8 +105,9 @@
|
|||||||
<b><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy
|
<b><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy
|
||||||
Siek</a></b> contributed the <a href="transform_iterator.htm">transform
|
Siek</a></b> contributed the <a href="transform_iterator.htm">transform
|
||||||
iterator</a> adaptor, the integer-only version of <tt><a href=
|
iterator</a> adaptor, the integer-only version of <tt><a href=
|
||||||
"counting_iterator.htm">counting_iterator_generator</a></tt>, and most of
|
"counting_iterator.htm">counting_iterator_generator</a></tt>,
|
||||||
the documentation.<br>
|
the <a href="function_output_iterator.htm">function output iterator</a>
|
||||||
|
adaptor, and most of the documentation.<br>
|
||||||
<b><a href="http://www.boost.org/people/john_potter.htm">John
|
<b><a href="http://www.boost.org/people/john_potter.htm">John
|
||||||
Potter</a></b> contributed the <tt><a href=
|
Potter</a></b> contributed the <tt><a href=
|
||||||
"projection_iterator.htm">projection_</a></tt> and <tt><a href=
|
"projection_iterator.htm">projection_</a></tt> and <tt><a href=
|
||||||
@@ -123,11 +131,11 @@
|
|||||||
<p><tt>iterator_adaptor</tt> is declared like this:
|
<p><tt>iterator_adaptor</tt> is declared like this:
|
||||||
<pre>
|
<pre>
|
||||||
template <class Base, class Policies,
|
template <class Base, class Policies,
|
||||||
class Value = typename std::iterator_traits<Base>::value_type,
|
class ValueOrNamedParams = typename std::iterator_traits<Base>::value_type,
|
||||||
class Reference = <i>...(see below)</i>,
|
class ReferenceOrNamedParams = <i>...(see below)</i>,
|
||||||
class Pointer = <i>...(see below)</i>,
|
class PointerOrNamedParams = <i>...(see below)</i>,
|
||||||
class Category = typename std::iterator_traits<Base>::iterator_category,
|
class CategoryOrNamedParams = typename std::iterator_traits<Base>::iterator_category,
|
||||||
class Distance = typename std::iterator_traits<Base>::difference_type>
|
class DistanceOrNamedParams = typename std::iterator_traits<Base>::difference_type>
|
||||||
struct iterator_adaptor;
|
struct iterator_adaptor;
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@@ -197,27 +205,99 @@ struct iterator_adaptor;
|
|||||||
<td>The <tt>difference_type</tt> for the resulting iterator.<br>
|
<td>The <tt>difference_type</tt> for the resulting iterator.<br>
|
||||||
<b>Default:</b>
|
<b>Default:</b>
|
||||||
<tt>std::iterator_traits<BaseType>::difference_type</tt>
|
<tt>std::iterator_traits<BaseType>::difference_type</tt>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td><tt>NamedParams</tt>
|
||||||
|
|
||||||
|
<td>A list of named template parameters generated using the
|
||||||
|
<a href="#iterator_traits_generator">
|
||||||
|
<tt>iterator_traits_generator</tt></a> class (see below).
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<h3><a name="named_template_parameters">Named Template Parameters</a></h3>
|
||||||
|
|
||||||
|
With seven template parameters, providing arguments for
|
||||||
|
<tt>iterator_adaptor</tt> in the correct order can be challenging.
|
||||||
|
Also, often times one would like to specify the sixth or seventh
|
||||||
|
template parameter, but use the defaults for the third through
|
||||||
|
fifth. As a solution to these problems we provide a mechanism for
|
||||||
|
naming the last five template parameters, and providing them in
|
||||||
|
any order through the <tt>iterator_traits_generator</tt> class.
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<pre>
|
||||||
|
<a name="iterator_traits_generator">class iterator_traits_generator</a>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template <class Value>
|
||||||
|
struct value_type : public <i>recursive magic</i> { };
|
||||||
|
|
||||||
|
template <class Reference>
|
||||||
|
struct reference : public <i>recursive magic</i> { };
|
||||||
|
|
||||||
|
template <class Pointer>
|
||||||
|
struct pointer : public <i>recursive magic</i> { };
|
||||||
|
|
||||||
|
template <class Distance>
|
||||||
|
struct difference_type : public <i>recursive magic</i> { };
|
||||||
|
|
||||||
|
template <class Category>
|
||||||
|
struct iterator_category : public <i>recursive magic</i> { };
|
||||||
|
};
|
||||||
|
</pre>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
The <tt>iterator_traits_generator</tt> is used to create a list of
|
||||||
|
of template arguments. For example, suppose you want to set the
|
||||||
|
<tt>Reference</tt> and <tt>Category</tt> parameters, and use the
|
||||||
|
defaults for the rest. Then you can use the traits generator as
|
||||||
|
follows:
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<pre>
|
||||||
|
iterator_traits_generator::reference<foo>::category<std::input_iterator_tag>
|
||||||
|
</pre>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
This generated type can then be passed into the <tt>iterator_adaptor</tt>
|
||||||
|
class to replace any of the last five parameters. If you use the traits
|
||||||
|
generator in the <i>i</i>th parameter position, then the parameters <i>i</i>
|
||||||
|
through 7 will use the types specified in the generator. For example, the
|
||||||
|
following adapts <tt>foo_iterator</tt> to create an <a href=
|
||||||
|
"http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a> with
|
||||||
|
<tt>reference</tt> type <tt>foo</tt>, and whose other traits are determined
|
||||||
|
according to the defaults described <a href="#template_parameters">above</a>.
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<pre>
|
||||||
|
iterator_adaptor<foo_iterator, foo_policies,
|
||||||
|
iterator_traits_generator
|
||||||
|
::reference<foo>
|
||||||
|
::iterator_category<std::input_iterator_tag>
|
||||||
|
>
|
||||||
|
</pre>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
|
||||||
<h3><a name="policies">The Policies Class</a></h3>
|
<h3><a name="policies">The Policies Class</a></h3>
|
||||||
|
|
||||||
<p>The main task in using <tt>iterator_adaptor</tt> is creating an
|
<p>The main task in using <tt>iterator_adaptor</tt> is creating an
|
||||||
appropriate <tt>Policies</tt> class. The <tt>Policies</tt> class will
|
appropriate <tt>Policies</tt> class. The <tt>Policies</tt> class will become
|
||||||
become the functional heart of the iterator adaptor, supplying the core
|
the functional heart of the resulting iterator, supplying the core
|
||||||
iterator operations that will determine how your new adaptor class will
|
operations that determine its behavior. The <tt>iterator_adaptor</tt>
|
||||||
behave. The <tt>iterator_adaptor</tt> template defines all of the operators
|
template defines all of the operators required of a <a href=
|
||||||
required of a <a href=
|
|
||||||
"http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
|
"http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
|
||||||
Iterator</a>. Your <tt>Policies</tt> class must implement three, four, or
|
Iterator</a> by dispatching to a <tt>Policies</tt> object. Your
|
||||||
seven of the core iterator operations below depending on the iterator
|
<tt>Policies</tt> class must implement a subset of the core iterator
|
||||||
categories you want it to support.<br>
|
operations below corresponding to the iterator categories you want it to
|
||||||
|
support.<br>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
|
||||||
<table border="1" summary="iterator_adaptor Policies operations">
|
<table border="1" summary="iterator_adaptor Policies operations">
|
||||||
<caption>
|
<caption>
|
||||||
<b>Core Iterator Operations</b><br>
|
<b>Core Iterator Operations</b><br>
|
||||||
<tt>T</tt>: iterator type; <tt>p</tt>: object of type T; <tt>n</tt>: <tt>T::size_type</tt>; <tt>x</tt>: <tt>T::difference_type</tt>; <tt>p1</tt>, <tt>p2</tt>: iterators
|
<tt>T</tt>: adapted iterator type; <tt>p</tt>: object of type T; <tt>n</tt>: <tt>T::size_type</tt>; <tt>x</tt>: <tt>T::difference_type</tt>; <tt>p1</tt>, <tt>p2</tt>: iterators
|
||||||
</caption>
|
</caption>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
@@ -360,7 +440,8 @@ struct <a name="default_iterator_policies">default_iterator_policies</a>
|
|||||||
range of iterators. If we had used concrete types above, we'd have tied the
|
range of iterators. If we had used concrete types above, we'd have tied the
|
||||||
usefulness of <tt>default_iterator_policies</tt> to a particular range of
|
usefulness of <tt>default_iterator_policies</tt> to a particular range of
|
||||||
adapted iterators. If you follow the same pattern with your
|
adapted iterators. If you follow the same pattern with your
|
||||||
<tt>Policies</tt> classes, you may achieve the same sort of reusability.
|
<tt>Policies</tt> classes, you can use them to generate more specialized
|
||||||
|
adaptors along the lines of <a href="#specialized_adaptors">those supplied by this library</a>.
|
||||||
|
|
||||||
<h3><a name="additional_members">Additional Members</a></h3>
|
<h3><a name="additional_members">Additional Members</a></h3>
|
||||||
In addition to all of the member functions required of a <a href=
|
In addition to all of the member functions required of a <a href=
|
||||||
@@ -751,8 +832,7 @@ bool operator==(const iterator_adaptor<B1,P,V1,R1,P1,C,D>&,
|
|||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<p>Revised
|
<p>Revised
|
||||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->15
|
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->09 Mar 2001<!--webbot bot="Timestamp" endspan i-checksum="14894" -->
|
||||||
Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14373" -->
|
|
||||||
|
|
||||||
|
|
||||||
<p>© Copyright Dave Abrahams and Jeremy Siek 2001. Permission to copy,
|
<p>© Copyright Dave Abrahams and Jeremy Siek 2001. Permission to copy,
|
||||||
@@ -779,6 +859,5 @@ bool operator==(const iterator_adaptor<B1,P,V1,R1,P1,C,D>&,
|
|||||||
<!-- LocalWords: iostream hpp sizeof InputIterator constness ConstIterator
|
<!-- LocalWords: iostream hpp sizeof InputIterator constness ConstIterator
|
||||||
David Abrahams
|
David Abrahams
|
||||||
-->
|
-->
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
// See http://www.boost.org for most recent version including documentation.
|
// See http://www.boost.org for most recent version including documentation.
|
||||||
|
|
||||||
// Revision History
|
// Revision History
|
||||||
|
// 04 Mar 2001 Patches for Intel C++ (Dave Abrahams)
|
||||||
// 19 Feb 2001 Take advantage of improved iterator_traits to do more tests
|
// 19 Feb 2001 Take advantage of improved iterator_traits to do more tests
|
||||||
// on MSVC. Reordered some #ifdefs for coherency.
|
// on MSVC. Reordered some #ifdefs for coherency.
|
||||||
// (David Abrahams)
|
// (David Abrahams)
|
||||||
@@ -153,7 +154,7 @@ input_iterator_test<std::istream_iterator<int>, int, std::ptrdiff_t, int*, int&,
|
|||||||
typedef ::std::char_traits<char>::off_type distance;
|
typedef ::std::char_traits<char>::off_type distance;
|
||||||
non_pointer_test<std::ostream_iterator<int>,int,
|
non_pointer_test<std::ostream_iterator<int>,int,
|
||||||
distance,int*,int&,std::output_iterator_tag> ostream_iterator_test;
|
distance,int*,int&,std::output_iterator_tag> ostream_iterator_test;
|
||||||
#elif defined(BOOST_MSVC) && !defined(__SGI_STL_PORT)
|
#elif defined(BOOST_MSVC_STD_ITERATOR)
|
||||||
non_pointer_test<std::ostream_iterator<int>,
|
non_pointer_test<std::ostream_iterator<int>,
|
||||||
int, void, void, void, std::output_iterator_tag>
|
int, void, void, void, std::output_iterator_tag>
|
||||||
ostream_iterator_test;
|
ostream_iterator_test;
|
||||||
|
@@ -371,7 +371,7 @@ Betty
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->10 Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14373" --></p>
|
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->28 Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14390" --></p>
|
||||||
<p><EFBFBD> Copyright Jeremy Siek 2000. Permission to copy, use,
|
<p><EFBFBD> Copyright Jeremy Siek 2000. Permission to copy, use,
|
||||||
modify, sell and distribute this document is granted provided this copyright
|
modify, sell and distribute this document is granted provided this copyright
|
||||||
notice appears in all copies. This document is provided "as is"
|
notice appears in all copies. This document is provided "as is"
|
||||||
|
@@ -312,8 +312,7 @@ simply use <tt>reverse_iterator_generator</tt> twice!<br><br>
|
|||||||
|
|
||||||
|
|
||||||
<p>Revised
|
<p>Revised
|
||||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->15
|
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->28 Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14390" -->
|
||||||
Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14373" -->
|
|
||||||
|
|
||||||
|
|
||||||
<p>© Copyright Jeremy Siek 2000. Permission to copy, use, modify, sell
|
<p>© Copyright Jeremy Siek 2000. Permission to copy, use, modify, sell
|
||||||
|
@@ -133,7 +133,7 @@ its argument.</TD>
|
|||||||
|
|
||||||
The transform iterator adaptor (the type
|
The transform iterator adaptor (the type
|
||||||
<tt>transform_iterator_generator<...>::type</tt>) is a model of <a
|
<tt>transform_iterator_generator<...>::type</tt>) is a model of <a
|
||||||
href="www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a><a href="#1">[1]</a>.
|
href="http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a><a href="#1">[1]</a>.
|
||||||
|
|
||||||
|
|
||||||
<h3>Members</h3>
|
<h3>Members</h3>
|
||||||
@@ -203,7 +203,7 @@ iterator always returns by-value.
|
|||||||
|
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->10 Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14373" --></p>
|
<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><EFBFBD> Copyright Jeremy Siek 2000. Permission to copy, use,
|
<p><EFBFBD> Copyright Jeremy Siek 2000. Permission to copy, use,
|
||||||
modify, sell and distribute this document is granted provided this copyright
|
modify, sell and distribute this document is granted provided this copyright
|
||||||
notice appears in all copies. This document is provided "as is"
|
notice appears in all copies. This document is provided "as is"
|
||||||
|
54
transform_iterator_test.cpp
Normal file
54
transform_iterator_test.cpp
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
|
||||||
|
// sell and distribute this software is granted provided this
|
||||||
|
// copyright notice appears in all copies. This software is provided
|
||||||
|
// "as is" without express or implied warranty, and with no claim as
|
||||||
|
// to its suitability for any purpose.
|
||||||
|
|
||||||
|
// Revision History
|
||||||
|
// 08 Mar 2001 Jeremy Siek
|
||||||
|
// Moved test of transform iterator into its own file. It to
|
||||||
|
// to be in iterator_adaptor_test.cpp.
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <boost/iterator_adaptors.hpp>
|
||||||
|
#include <boost/pending/iterator_tests.hpp>
|
||||||
|
|
||||||
|
struct mult_functor {
|
||||||
|
typedef int result_type;
|
||||||
|
typedef int argument_type;
|
||||||
|
// Functors used with transform_iterator must be
|
||||||
|
// DefaultConstructible, as the transform_iterator must be
|
||||||
|
// DefaultConstructible to satisfy the requirements for
|
||||||
|
// TrivialIterator.
|
||||||
|
mult_functor() { }
|
||||||
|
mult_functor(int aa) : a(aa) { }
|
||||||
|
int operator()(int b) const { return a * b; }
|
||||||
|
int a;
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
const int N = 10;
|
||||||
|
|
||||||
|
// Borland is getting confused about typedef's and constructors here
|
||||||
|
|
||||||
|
// Test transform_iterator
|
||||||
|
{
|
||||||
|
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::transform_iterator_generator<mult_functor, int*>::type i(y, mult_functor(2));
|
||||||
|
boost::input_iterator_test(i, x[0], x[1]);
|
||||||
|
boost::input_iterator_test(boost::make_transform_iterator(&y[0], mult_functor(2)), x[0], x[1]);
|
||||||
|
}
|
||||||
|
std::cout << "test successful " << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
@@ -93,7 +93,7 @@ destructor declarations. He says "Probably this concern is misplaced, becau
|
|||||||
noncopyable will be used mostly for classes which own resources and thus have non-trivial destruction semantics."</p>
|
noncopyable will be used mostly for classes which own resources and thus have non-trivial destruction semantics."</p>
|
||||||
<hr>
|
<hr>
|
||||||
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan
|
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan
|
||||||
-->28 September, 2000<!--webbot bot="Timestamp" endspan i-checksum="39343"
|
-->28 February, 2001<!--webbot bot="Timestamp" endspan i-checksum="40412"
|
||||||
-->
|
-->
|
||||||
</p>
|
</p>
|
||||||
<p><EFBFBD> Copyright boost.org 1999. Permission to copy, use, modify, sell and
|
<p><EFBFBD> Copyright boost.org 1999. Permission to copy, use, modify, sell and
|
||||||
|
Reference in New Issue
Block a user