Compare commits

...

20 Commits

Author SHA1 Message Date
nobody
d944c6538f This commit was manufactured by cvs2svn to create tag
'Version_1_21_0'.

[SVN r9525]
2001-03-09 14:58:07 +00:00
Beman Dawes
feb370b201 1.21.0 run up including fixing broken links
[SVN r9523]
2001-03-09 14:36:41 +00:00
Dave Abrahams
d1b34e64d8 Fixes for validator.w3.org
[SVN r9518]
2001-03-09 03:28:13 +00:00
Dave Abrahams
b9a1eead40 Mostly clarification. Fix: changed "category" to "iterator_category" in one place.
[SVN r9517]
2001-03-09 03:10:32 +00:00
Jeremy Siek
1e4bfac98c added named template parameter to table of contents
[SVN r9510]
2001-03-08 21:36:09 +00:00
Jeremy Siek
3bb504fbf3 added revision history line
[SVN r9506]
2001-03-08 20:50:14 +00:00
Jeremy Siek
5029791c90 split off indirect and transform tests into separate files
[SVN r9505]
2001-03-08 20:49:05 +00:00
Beman Dawes
a1a68f0970 1.21.0 run up
[SVN r9502]
2001-03-08 20:35:52 +00:00
Jeremy Siek
f8543d79eb added more static asserts
[SVN r9500]
2001-03-08 20:02:00 +00:00
Jeremy Siek
f353415136 added docs for iterator_traits_generator
[SVN r9498]
2001-03-08 19:19:46 +00:00
Jeremy Siek
26240403b0 added a test to make sure that the type set by the generator is really the
type used


[SVN r9497]
2001-03-08 19:04:29 +00:00
Jeremy Siek
3a39729b58 new file
[SVN r9488]
2001-03-08 16:33:40 +00:00
Dave Abrahams
096c961d9a Patches for Intel C++
[SVN r9425]
2001-03-04 16:08:20 +00:00
Dave Abrahams
01fe04a6a2 Workaround for Borland
[SVN r9424]
2001-03-04 16:07:11 +00:00
John Maddock
7ea4014993 Misc fixes that missed the last commit..
[SVN r9402]
2001-03-04 11:08:29 +00:00
Beman Dawes
d50b374f88 Boost Test Library initial commit
[SVN r9364]
2001-02-28 21:39:56 +00:00
Jeremy Siek
27dfb25570 added function output iterator adaptor
[SVN r9351]
2001-02-27 05:50:51 +00:00
John Maddock
b5ed77985e added missing typename's to docs
[SVN r9324]
2001-02-25 12:04:48 +00:00
John Maddock
61243bd15f type_traits: more tentative EDG compiler fixes...
[SVN r9321]
2001-02-24 13:04:56 +00:00
Dave Abrahams
368b94d804 Corrected numeric_limits<>::is_integral -> numeric_limits<>::is_integer
[SVN r9299]
2001-02-20 23:15:29 +00:00
18 changed files with 674 additions and 241 deletions

View File

@@ -34,9 +34,9 @@ specialization or member templates, no benefit will occur from
using call_traits: the call_traits defined types will always be
the same as the existing practice in this case. In addition if
only member templates and not partial template specialisation is
support by the compiler (for example Visual C++ 6) then call_traits
can not be used with array types (although it can be used to
solve the reference to reference problem).</p>
support by the compiler (for example Visual C++ 6) then
call_traits can not be used with array types (although it can be
used to solve the reference to reference problem).</p>
<table border="0" cellpadding="7" cellspacing="1" width="797">
<tr>
@@ -79,7 +79,8 @@ solve the reference to reference problem).</p>
</td>
</tr>
<tr>
<td valign="top" width="17%"><p align="center">const T&amp;<br>
<td valign="top" width="17%"><p align="center">const
T&amp;<br>
(return value)</p>
</td>
<td valign="top" width="35%"><p align="center"><code>call_traits&lt;T&gt;::const_reference</code></p>
@@ -91,7 +92,8 @@ solve the reference to reference problem).</p>
</td>
</tr>
<tr>
<td valign="top" width="17%"><p align="center">const T&amp;<br>
<td valign="top" width="17%"><p align="center">const
T&amp;<br>
(function parameter)</p>
</td>
<td valign="top" width="35%"><p align="center"><code>call_traits&lt;T&gt;::param_type</code></p>
@@ -332,8 +334,8 @@ possible:</p>
<p>The following table shows the effect that call_traits has on
various types, the table assumes that the compiler supports
partial specialization: if it doesn't then all types behave in
the same way as the entry for &quot;myclass&quot;, and call_traits
can not be used with reference or array types.</p>
the same way as the entry for &quot;myclass&quot;, and
call_traits can not be used with reference or array types.</p>
<table border="0" cellpadding="7" cellspacing="1" width="766">
<tr>
@@ -388,7 +390,8 @@ can not be used with reference or array types.</p>
</td>
<td valign="top" width="17%"><p align="center">int&amp;</p>
</td>
<td valign="top" width="17%"><p align="center">const int&amp;</p>
<td valign="top" width="17%"><p align="center">const
int&amp;</p>
</td>
<td valign="top" width="17%"><p align="center">int const</p>
</td>
@@ -420,7 +423,8 @@ can not be used with reference or array types.</p>
</td>
<td valign="top" width="17%"><p align="center">int&amp;</p>
</td>
<td valign="top" width="17%"><p align="center">const int&amp;</p>
<td valign="top" width="17%"><p align="center">const
int&amp;</p>
</td>
<td valign="top" width="17%"><p align="center">int&amp;</p>
</td>
@@ -432,13 +436,17 @@ can not be used with reference or array types.</p>
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
align="center">const int&amp;</p>
</td>
<td valign="top" width="17%"><p align="center">const int&amp;</p>
<td valign="top" width="17%"><p align="center">const
int&amp;</p>
</td>
<td valign="top" width="17%"><p align="center">const int&amp;</p>
<td valign="top" width="17%"><p align="center">const
int&amp;</p>
</td>
<td valign="top" width="17%"><p align="center">const int&amp;</p>
<td valign="top" width="17%"><p align="center">const
int&amp;</p>
</td>
<td valign="top" width="17%"><p align="center">const int&amp;</p>
<td valign="top" width="17%"><p align="center">const
int&amp;</p>
</td>
<td valign="top" width="17%"><p align="center">All
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
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
typedefs may be used:</p>
file), the aim is to illustrate how each of the available
call_traits typedefs may be used:</p>
<pre>template &lt;class T&gt;
struct contained
@@ -523,14 +531,14 @@ problem):</h4>
<pre>template &lt;class Operation&gt;
class binder1st :
public unary_function&lt;Operation::second_argument_type, Operation::result_type&gt;
public unary_function&lt;typename Operation::second_argument_type, typename Operation::result_type&gt;
{
protected:
Operation op;
Operation::first_argument_type value;
typename Operation::first_argument_type value;
public:
binder1st(const Operation&amp; x, const Operation::first_argument_type&amp; y);
Operation::result_type operator()(const Operation::second_argument_type&amp; x) const;
binder1st(const Operation&amp; x, const typename Operation::first_argument_type&amp; y);
typename Operation::result_type operator()(const typename Operation::second_argument_type&amp; x) const;
}; </pre>
<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>
to use call_traits:</p>
<pre>Operation::result_type operator()(call_traits&lt;Operation::second_argument_type&gt;::param_type x) const;</pre>
<pre>typename Operation::result_type operator()(typename call_traits&lt;typename Operation::second_argument_type&gt;::param_type x) const;</pre>
<p>Now in the case that <code>Operation::second_argument_type</code>
is a reference type, the argument is passed as a reference, and
@@ -575,9 +583,9 @@ std::pair&lt;
degraded to pointers if the deduced types are arrays, similar
situations occur in the standard binders and adapters: in
principle in any function that &quot;wraps&quot; a temporary
whose type is deduced. Note that the function arguments to make_pair
are not expressed in terms of call_traits: doing so would prevent
template argument deduction from functioning.</p>
whose type is deduced. Note that the function arguments to
make_pair are not expressed in terms of call_traits: doing so
would prevent template argument deduction from functioning.</p>
<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>For reference types the rational follows <a href="#refs">Example
2</a> - references to references are not allowed, so the call_traits
members must be defined such that these problems do not occur.
There is a proposal to modify the language such that &quot;a
reference to a reference is a reference&quot; (issue #106,
2</a> - references to references are not allowed, so the
call_traits members must be defined such that these problems do
not occur. There is a proposal to modify the language such that
&quot;a reference to a reference is a reference&quot; (issue #106,
submitted by Bjarne Stroustrup), call_traits&lt;T&gt;::value_type
and call_traits&lt;T&gt;::param_type both provide the same effect
as that proposal, without the need for a language change (in
@@ -687,11 +695,11 @@ struct A
void foo(T t);
};</pre>
<p><font face="Times New Roman">In this case if we instantiate A&lt;int[2]&gt;
then the declared type of the parameter passed to member function
foo is int[2], but it's actual type is const int*, if we try to
use the type T within the function body, then there is a strong
likelyhood that our code will not compile:</font></p>
<p><font face="Times New Roman">In this case if we instantiate
A&lt;int[2]&gt; then the declared type of the parameter passed to
member function foo is int[2], but it's actual type is const int*,
if we try to use the type T within the function body, then there
is a strong likelyhood that our code will not compile:</font></p>
<pre>template &lt;class T&gt;
void A&lt;T&gt;::foo(T t)
@@ -706,13 +714,13 @@ declared type:</p>
<pre>template &lt;class T&gt;
struct A
{
void foo(call_traits&lt;T&gt;::value_type t);
void foo(typename call_traits&lt;T&gt;::value_type t);
};
template &lt;class T&gt;
void A&lt;T&gt;::foo(call_traits&lt;T&gt;::value_type t)
void A&lt;T&gt;::foo(typename call_traits&lt;T&gt;::value_type t)
{
call_traits&lt;T&gt;::value_type dup(t); // OK even if T is an array type.
typename call_traits&lt;T&gt;::value_type dup(t); // OK even if T is an array type.
}</pre>
<p>For value_type (return by value), again only a pointer may be

View File

@@ -117,13 +117,14 @@ void call_traits_checker<T>::operator()(param_type p)
assert(t == c.value());
assert(t == c.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() << ">::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() << ">::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 << endl;
#endif
}
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
@@ -373,3 +374,4 @@ unsigned int expected_failures = 0;
#endif

View File

@@ -96,11 +96,11 @@ int main(int argc, char *argv[ ])
cp7.first();
double* pd = cp7.second();
#endif
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>)))
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>)))
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, int>) < sizeof(std::pair<empty_UDT, int>)))
soft_value_test(true, (sizeof(compressed_pair<int, empty_UDT>) < sizeof(std::pair<int, empty_UDT>)))
soft_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_POD_UDT>) < sizeof(std::pair<empty_UDT, empty_POD_UDT>)))
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);
}
@@ -147,15 +147,7 @@ template compressed_pair<double, int[2]>::compressed_pair();
#endif // __MWERKS__
#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;
#endif

View File

@@ -282,7 +282,7 @@ template &lt;class Incrementable&gt;
struct counting_iterator_traits
{
if (numeric_limits&lt;Incrementable&gt::is_specialized) {
if (!numeric_limits&lt;Incrementable&gt::is_integral)
if (!numeric_limits&lt;Incrementable&gt::is_integer)
COMPILE_TIME_ERROR;
if (!numeric_limits&lt;Incrementable&gt::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.
<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,
modify, sell and distribute this document is granted provided this copyright
notice appears in all copies. This document is provided &quot;as is&quot;

View File

@@ -168,8 +168,8 @@ this parameter is the appropriate type.<br>
The filter iterator adaptor (the type
<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="www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</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.
@@ -261,7 +261,7 @@ default).
<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,
modify, sell and distribute this document is granted provided this copyright
notice appears in all copies. This document is provided &quot;as is&quot;

41
fun_out_iter_example.cpp Normal file
View 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;
}

View 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 &lt;class UnaryFunction&gt;
class function_output_iterator;
template &lt;class UnaryFunction&gt;
function_output_iterator&lt;UnaryFunction&gt;
make_function_output_iterator(const UnaryFunction&amp; 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 &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;boost/function_output_iterator.hpp&gt;
struct string_appender {
string_appender(std::string&amp; s) : m_str(s) { }
void operator()(const std::string&amp; x) const {
m_str += x;
}
std::string&amp; m_str;
};
int main(int, char*[])
{
std::vector&lt;std::string&gt; 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 &lt;&lt; s &lt;&lt; std::endl;
return 0;
}
</pre>
</blockquote>
<hr>
<h2><a name="function_output_iterator">The Function Output Iterator Class</a></h2>
<blockquote>
<pre>
template &lt;class UnaryFunction&gt;
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 &lt;class UnaryFunction&gt;
function_output_iterator&lt;UnaryFunction&gt;
make_function_output_iterator(const UnaryFunction&amp; f = UnaryFunction())
</pre>
</blockquote>
<hr>
<p>&copy; 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>

View File

@@ -422,8 +422,7 @@ a,b,c,d,e,f,g,
<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" -->
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->28 Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14390" -->
<p>&copy; Copyright Jeremy Siek and David Abrahams 2001. Permission to

151
indirect_iterator_test.cpp Normal file
View 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
View 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;
}

View File

@@ -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,
// sell and distribute this software is granted provided this
@@ -9,6 +9,8 @@
// See http://www.boost.org for most recent version including documentation.
// 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
// on MSVC. Hack around an MSVC-with-STLport internal compiler
// error. (David Abrahams)
@@ -59,28 +61,6 @@ struct my_iterator_tag : public std::random_access_iterator_tag { };
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 {
typedef int result_type;
@@ -117,78 +97,6 @@ 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);
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()
{
@@ -210,67 +118,14 @@ main()
// 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);
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::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
{
typedef std::pair<dummyT,dummyT> Pair;
@@ -376,23 +231,33 @@ main()
// Test filter iterator
{
// Using typedefs for filter_gen::type and filter_gen::policies_type
// confused Borland terribly.
// Using typedefs for filter_gen::type confused Borland terribly.
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
, dummyT
#endif
>::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));
boost::forward_iterator_test(i, dummyT(1), dummyT(4));
#endif
#if !defined(__BORLANDC__)
//
enum { is_forward = boost::is_same<
filter_iter::iterator_category,
std::forward_iterator_tag>::value };
BOOST_STATIC_ASSERT(is_forward);
#endif
// On compilers not supporting partial specialization, we can do more type
// deduction with deque iterators than with pointers... unless the library
@@ -433,12 +298,24 @@ main()
// check operator-> with a forward iterator
{
boost::forward_iterator_archetype<dummyT> forward_iter;
#if defined(__BORLANDC__)
typedef boost::iterator_adaptor<boost::forward_iterator_archetype<dummyT>,
boost::default_iterator_policies,
dummyT, const dummyT&, const dummyT*,
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);
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());
}
// check operator-> with an input iterator
@@ -449,10 +326,10 @@ main()
dummyT, const dummyT&, const dummyT*,
std::input_iterator_tag, std::ptrdiff_t> adaptor_type;
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());
}
std::cout << "test successful " << std::endl;
return 0;
}

View File

@@ -44,6 +44,8 @@
<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="#additional_members">Additional Class Members</a>
@@ -63,7 +65,7 @@
</ul>
<li>
Specialized Iterator Adaptors
<a name="specialized_adaptors">Specialized Iterator Adaptors</a>
<ul>
<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>
<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>
<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
Siek</a></b> contributed the <a href="transform_iterator.htm">transform
iterator</a> adaptor, the integer-only version of <tt><a href=
"counting_iterator.htm">counting_iterator_generator</a></tt>, and most of
the documentation.<br>
"counting_iterator.htm">counting_iterator_generator</a></tt>,
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
Potter</a></b> contributed the <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:
<pre>
template &lt;class Base, class Policies,
class Value = typename std::iterator_traits&lt;Base&gt;::value_type,
class Reference = <i>...(see below)</i>,
class Pointer = <i>...(see below)</i>,
class Category = typename std::iterator_traits&lt;Base&gt;::iterator_category,
class Distance = typename std::iterator_traits&lt;Base&gt;::difference_type&gt;
class ValueOrNamedParams = typename std::iterator_traits&lt;Base&gt;::value_type,
class ReferenceOrNamedParams = <i>...(see below)</i>,
class PointerOrNamedParams = <i>...(see below)</i>,
class CategoryOrNamedParams = typename std::iterator_traits&lt;Base&gt;::iterator_category,
class DistanceOrNamedParams = typename std::iterator_traits&lt;Base&gt;::difference_type&gt;
struct iterator_adaptor;
</pre>
@@ -197,27 +205,99 @@ struct iterator_adaptor;
<td>The <tt>difference_type</tt> for the resulting iterator.<br>
<b>Default:</b>
<tt>std::iterator_traits&lt;BaseType&gt;::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>
<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 &lt;class Value&gt;
struct value_type : public <i>recursive magic</i> { };
template &lt;class Reference&gt;
struct reference : public <i>recursive magic</i> { };
template &lt;class Pointer&gt;
struct pointer : public <i>recursive magic</i> { };
template &lt;class Distance&gt;
struct difference_type : public <i>recursive magic</i> { };
template &lt;class Category&gt;
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&lt;foo&gt;::category&lt;std::input_iterator_tag&gt;
</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&lt;foo_iterator, foo_policies,
iterator_traits_generator
::reference&lt;foo&gt;
::iterator_category&lt;std::input_iterator_tag&gt;
&gt;
</pre>
</blockquote>
<h3><a name="policies">The Policies Class</a></h3>
<p>The main task in using <tt>iterator_adaptor</tt> is creating an
appropriate <tt>Policies</tt> class. The <tt>Policies</tt> class will
become the functional heart of the iterator adaptor, supplying the core
iterator operations that will determine how your new adaptor class will
behave. The <tt>iterator_adaptor</tt> template defines all of the operators
required of a <a href=
appropriate <tt>Policies</tt> class. The <tt>Policies</tt> class will become
the functional heart of the resulting iterator, supplying the core
operations that determine its behavior. The <tt>iterator_adaptor</tt>
template defines all of the operators required of a <a href=
"http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
Iterator</a>. Your <tt>Policies</tt> class must implement three, four, or
seven of the core iterator operations below depending on the iterator
categories you want it to support.<br>
Iterator</a> by dispatching to a <tt>Policies</tt> object. Your
<tt>Policies</tt> class must implement a subset of the core iterator
operations below corresponding to the iterator categories you want it to
support.<br>
<br>
<table border="1" summary="iterator_adaptor Policies operations">
<caption>
<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>
<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
usefulness of <tt>default_iterator_policies</tt> to a particular range of
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>
In addition to all of the member functions required of a <a href=
@@ -751,8 +832,7 @@ bool operator==(const iterator_adaptor&lt;B1,P,V1,R1,P1,C,D&gt;&amp;,
<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" -->
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->09 Mar 2001<!--webbot bot="Timestamp" endspan i-checksum="14894" -->
<p>&copy; Copyright Dave Abrahams and Jeremy Siek 2001. Permission to copy,
@@ -779,6 +859,5 @@ bool operator==(const iterator_adaptor&lt;B1,P,V1,R1,P1,C,D&gt;&amp;,
<!-- LocalWords: iostream hpp sizeof InputIterator constness ConstIterator
David Abrahams
-->
</body>
</html>

View File

@@ -7,6 +7,7 @@
// See http://www.boost.org for most recent version including documentation.
// Revision History
// 04 Mar 2001 Patches for Intel C++ (Dave Abrahams)
// 19 Feb 2001 Take advantage of improved iterator_traits to do more tests
// on MSVC. Reordered some #ifdefs for coherency.
// (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;
non_pointer_test<std::ostream_iterator<int>,int,
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>,
int, void, void, void, std::output_iterator_tag>
ostream_iterator_test;

View File

@@ -371,7 +371,7 @@ Betty
</pre>
<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,
modify, sell and distribute this document is granted provided this copyright
notice appears in all copies. This document is provided &quot;as is&quot;

View File

@@ -312,8 +312,7 @@ simply use <tt>reverse_iterator_generator</tt> twice!<br><br>
<p>Revised
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->15
Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14373" -->
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->28 Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14390" -->
<p>&copy; Copyright Jeremy Siek 2000. Permission to copy, use, modify, sell

View File

@@ -133,7 +133,7 @@ its argument.</TD>
The transform iterator adaptor (the type
<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>
@@ -203,7 +203,7 @@ iterator always returns by-value.
<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,
modify, sell and distribute this document is granted provided this copyright
notice appears in all copies. This document is provided &quot;as is&quot;

View 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;
}

View File

@@ -93,7 +93,7 @@ destructor declarations. He says &quot;Probably this concern is misplaced, becau
noncopyable will be used mostly for classes which own resources and thus have non-trivial destruction semantics.&quot;</p>
<hr>
<p>Revised&nbsp; <!--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><EFBFBD> Copyright boost.org 1999. Permission to copy, use, modify, sell and