Compare commits

...

5 Commits

Author SHA1 Message Date
7c560d1d5a This commit was manufactured by cvs2svn to create tag
'Version_1_29_0'.

[SVN r15904]
2002-10-11 15:17:55 +00:00
0c34bf4fb4 Point to my "home page"
[SVN r15895]
2002-10-11 09:44:39 +00:00
eb234b3e66 Tidy up the HTML
[SVN r15838]
2002-10-10 05:12:07 +00:00
4482f886f1 function.hpp:
- Work around SGI MIPSpro bug that affects Boost.Python


[SVN r15515]
2002-09-25 18:12:13 +00:00
cd9f10006b This commit was manufactured by cvs2svn to create branch 'RC_1_29_0'.
[SVN r15460]
2002-09-19 20:49:39 +00:00
5 changed files with 177 additions and 172 deletions

View File

@ -5,7 +5,7 @@
</head> </head>
<body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080"> <body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080">
<h1><IMG SRC="../../../c++boost.gif" WIDTH="276" HEIGHT="86">boost::function Frequently Asked Questions</h1> <h1><IMG SRC="../../../c++boost.gif" WIDTH="276" HEIGHT="86" alt="C++ Boost">boost::function Frequently Asked Questions</h1>
<h2>Q: I see void pointers; is this [mess] type safe?</h2> <h2>Q: I see void pointers; is this [mess] type safe?</h2>
<p>Yes, <code>boost::function</code> is type safe even though it uses void pointers and pointers to functions returning void and taking no arguments. Essentially, all type information is encoded in the functions that manage and invoke function pointers and function objects. Only these functions are instantiated with the exact type that is pointed to by the void pointer or pointer to void function. The reason that both are required is that one may cast between void pointers and object pointers safely or between different types of function pointers (provided you don't invoke a function pointer with the wrong type). <p>Yes, <code>boost::function</code> is type safe even though it uses void pointers and pointers to functions returning void and taking no arguments. Essentially, all type information is encoded in the functions that manage and invoke function pointers and function objects. Only these functions are instantiated with the exact type that is pointed to by the void pointer or pointer to void function. The reason that both are required is that one may cast between void pointers and object pointers safely or between different types of function pointers (provided you don't invoke a function pointer with the wrong type).
@ -21,7 +21,7 @@ void g() { return f(); }
<pre> <pre>
int do_something(int); int do_something(int);
boost::function<void, int> f; boost::function&lt;void, int&gt; f;
f = do_something; f = do_something;
</pre> </pre>
<p> This is a valid usage of <code>boost::function</code> because void returns are not used. With void returns, we would attempting to compile ill-formed code similar to: <p> This is a valid usage of <code>boost::function</code> because void returns are not used. With void returns, we would attempting to compile ill-formed code similar to:
@ -35,10 +35,10 @@ void g() { return f(); }
<p> In November and December of 2000, the issue of cloning vs. reference counting was debated at length and it was decided that cloning gave more predictable semantics. I won't rehash the discussion here, but if it cloning is incorrect for a particular application a reference-counting allocator could be used. <p> In November and December of 2000, the issue of cloning vs. reference counting was debated at length and it was decided that cloning gave more predictable semantics. I won't rehash the discussion here, but if it cloning is incorrect for a particular application a reference-counting allocator could be used.
<hr> <hr>
<address><a href="mailto:gregod@cs.rpi.edu">Doug Gregor</a></address> <address><a href="http://www.cs.rpi.edu/~gregod">Doug Gregor</a></address>
<!-- Created: Fri Feb 16 09:30:41 EST 2001 --> <!-- Created: Fri Feb 16 09:30:41 EST 2001 -->
<!-- hhmts start --> <!-- hhmts start -->
Last modified: Wed Nov 7 15:11:52 EST 2001 Last modified: Fri Oct 11 05:39:27 EDT 2002
<!-- hhmts end --> <!-- hhmts end -->
</body> </body>
</html> </html>

View File

@ -6,9 +6,9 @@
<body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080"> <body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080">
<h1><IMG SRC="../../../c++boost.gif" WIDTH="276" HEIGHT="86">Boost.Function Reference Manual</h1> <h1><IMG SRC="../../../c++boost.gif" WIDTH="276" HEIGHT="86" alt="C++ Boost">Boost.Function Reference Manual</h1>
<h2><a name="header">Header <code>&lt;<a href="../../../boost/function.hpp">boost/function.hpp</a>&gt;</code> synopsis</a></h2> <h2><a name="header">Header</a> <code>&lt;<a href="../../../boost/function.hpp">boost/function.hpp</a>&gt;</code> synopsis</h2>
<p> Here <code><i>MAX_ARGS</i></code> is an implementation-defined constant that defines the maximum number of function arguments supported by Boost.Function and will be at least 10. The <code><i>MAX_ARGS</i></code> constant referred to in this document need not have any direct representation in the library. <p> Here <code><i>MAX_ARGS</i></code> is an implementation-defined constant that defines the maximum number of function arguments supported by Boost.Function and will be at least 10. The <code><i>MAX_ARGS</i></code> constant referred to in this document need not have any direct representation in the library.
<pre> <pre>
@ -84,7 +84,7 @@
function<em>N</em>&lt;ResultType, Arg1, Arg2, <i>...</i>, Arg<i>N</i>, Policy, Mixin, Allocator&gt;<b>&amp;</b>); function<em>N</em>&lt;ResultType, Arg1, Arg2, <i>...</i>, Arg<i>N</i>, Policy, Mixin, Allocator&gt;<b>&amp;</b>);
// For any <i>N</i> in [0, <i>MAX_ARGS</i>] // For any <i>N</i> in [0, <i>MAX_ARGS</i>]
<b>template</b>&lt;<b>typename</b> Signature, <em>// Function type: ResultType (Arg1, Arg2, ..., Arg<em>N</em>)</em> <b>template</b>&lt;<b>typename</b> Signature, <em>// Function type: ResultType (Arg1, Arg2, ..., ArgN)</em>
<b>typename</b> Policy = empty_function_policy, <em>// Deprecated</em> <b>typename</b> Policy = empty_function_policy, <em>// Deprecated</em>
<b>typename</b> Mixin = empty_function_mixin, <em>// Deprecated</em> <b>typename</b> Mixin = empty_function_mixin, <em>// Deprecated</em>
<b>typename</b> Allocator = std::allocator&lt;function_base&gt; &gt; <b>typename</b> Allocator = std::allocator&lt;function_base&gt; &gt;
@ -112,7 +112,6 @@
</pre> </pre>
<h2>Definitions</h2> <h2>Definitions</h2>
<p>
<ul> <ul>
<li><a name="compatible"></a>A function object <code>f</code> is <em>compatible</em> if for the given set of argument types <code>Arg1</code>, <code>Arg2</code>, ..., <code>Arg<em>N</em></code> and a return type <code>ResultType</code>, the appropriate following function is well-formed: <li><a name="compatible"></a>A function object <code>f</code> is <em>compatible</em> if for the given set of argument types <code>Arg1</code>, <code>Arg2</code>, ..., <code>Arg<em>N</em></code> and a return type <code>ResultType</code>, the appropriate following function is well-formed:
<pre> <pre>
@ -172,7 +171,7 @@
<li><b>Throws</b>: will not throw when <code>g</code> is a <a href="#stateless">stateless</a> function object unless construction of the <code>Mixin</code> subobject throws.</li> <li><b>Throws</b>: will not throw when <code>g</code> is a <a href="#stateless">stateless</a> function object unless construction of the <code>Mixin</code> subobject throws.</li>
</ul> </ul>
<p> <a name="functionN_target_ref"><code><b>template</b>&lt;<b>typename</b> F&gt; function<i>N</i>(<a href="../../bind/ref.html">reference_wrapper</a>&lt;F&gt; g);</code></a> <p> <a name="functionN_target_ref"></a><code><b>template</b>&lt;<b>typename</b> F&gt; function<i>N</i>(<a href="../../bind/ref.html">reference_wrapper</a>&lt;F&gt; g);</code>
<ul> <ul>
<li><b>Requires</b>: <code>g.get()</code> is a <a href="#compatible">compatible</a> function object.</li> <li><b>Requires</b>: <code>g.get()</code> is a <a href="#compatible">compatible</a> function object.</li>
<li><b>Effects</b>: Constructs the <code>Mixin</code> subobject from the given mixin.</li> <li><b>Effects</b>: Constructs the <code>Mixin</code> subobject from the given mixin.</li>
@ -195,7 +194,7 @@
<li><b>Throws</b>: will not throw when <code>g</code> is a <a href="#stateless">stateless</a> function object.</li> <li><b>Throws</b>: will not throw when <code>g</code> is a <a href="#stateless">stateless</a> function object.</li>
</ul> </ul>
<p> <a name="functionN_target_ref_assn"><code><b>template</b>&lt;<b>typename</b> F&gt; function<i>N</i><b>&amp;</b> <b>operator</b>=(<a href="../../bind/ref.html">reference_wrapper</a>&lt;F&gt; g);</code></a> <p> <a name="functionN_target_ref_assn"></a><code><b>template</b>&lt;<b>typename</b> F&gt; function<i>N</i><b>&amp;</b> <b>operator</b>=(<a href="../../bind/ref.html">reference_wrapper</a>&lt;F&gt; g);</code>
<ul> <ul>
<li><b>Requires</b>: <code>g.get()</code> is a <a href="#compatible">compatible</a> function object.</li> <li><b>Requires</b>: <code>g.get()</code> is a <a href="#compatible">compatible</a> function object.</li>
<li><b>Postconditions</b>: <code>f</code> targets <code>g.get()</code> (not a copy of <code>g.get()</code>) if <code>g.get()</code> is nonempty, or <code>f.<a href="#empty">empty</a>()</code> if <code>g.get()</code> is empty.</li> <li><b>Postconditions</b>: <code>f</code> targets <code>g.get()</code> (not a copy of <code>g.get()</code>) if <code>g.get()</code> is nonempty, or <code>f.<a href="#empty">empty</a>()</code> if <code>g.get()</code> is empty.</li>
@ -260,7 +259,6 @@
<p> The semantics of all operations in class template <code>function</code> are equivalent to that of the underlying <code>function<i>N</i></code> object, although additional member functions are required to allow proper copy construction and copy assignment of <code>function</code> objects. <p> The semantics of all operations in class template <code>function</code> are equivalent to that of the underlying <code>function<i>N</i></code> object, although additional member functions are required to allow proper copy construction and copy assignment of <code>function</code> objects.
<h2><a name="operations">Operations</a></h2> <h2><a name="operations">Operations</a></h2>
<p>
<pre> <pre>
<b>template</b>&lt;<b>typename</b> ResultType, <b>template</b>&lt;<b>typename</b> ResultType,
<b>typename</b> Arg1, <b>typename</b> Arg1,
@ -277,7 +275,6 @@
<li><b>Effects</b>: <code>f.<a href="#functionN_swap">swap</a>(g);</code></li> <li><b>Effects</b>: <code>f.<a href="#functionN_swap">swap</a>(g);</code></li>
</ul> </ul>
<p>
<pre> <pre>
<b>template</b>&lt;<b>typename</b> Signature, <b>typename</b> Policy, <b>typename</b> Mixin, <b>typename</b> Allocator&gt; <b>template</b>&lt;<b>typename</b> Signature, <b>typename</b> Policy, <b>typename</b> Mixin, <b>typename</b> Allocator&gt;
<b>void</b> <a name="swap_function">swap</a>(function&lt;Signature, Policy, Mixin, Allocator&gt;<b>&amp;</b> f, <b>void</b> <a name="swap_function">swap</a>(function&lt;Signature, Policy, Mixin, Allocator&gt;<b>&amp;</b> f,
@ -290,10 +287,10 @@
<hr> <hr>
<p><a name="novoid">[1]</a> On compilers not supporting void returns, when the <code>ReturnType</code> is <b>void</b>, the <code>result_type</code> of a Boost.Function object is implementation-defined. <p><a name="novoid">[1]</a> On compilers not supporting void returns, when the <code>ReturnType</code> is <b>void</b>, the <code>result_type</code> of a Boost.Function object is implementation-defined.
<hr> <hr>
<address><a href="mailto:gregod@cs.rpi.edu">Douglas Gregor</a></address> <address><a href="http://www.cs.rpi.edu/~gregod">Doug Gregor</a></address>
<!-- Created: Fri Jul 13 10:57:20 EDT 2001 --> <!-- Created: Fri Jul 13 10:57:20 EDT 2001 -->
<!-- hhmts start --> <!-- hhmts start -->
Last modified: Fri Sep 6 14:46:50 EDT 2002 Last modified: Fri Oct 11 05:40:09 EDT 2002
<!-- hhmts end --> <!-- hhmts end -->
</body> </body>
</html> </html>

View File

@ -6,17 +6,17 @@
<body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080"> <body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080">
<h1><IMG SRC="../../../c++boost.gif" WIDTH="276" HEIGHT="86">Boost.Function Tutorial</h1> <h1><IMG SRC="../../../c++boost.gif" WIDTH="276" HEIGHT="86" alt="C++ Boost">Boost.Function Tutorial</h1>
<p> Boost.Function has two syntactical forms: the preferred form and the compatibility form. The preferred form fits more closely with the C++ language and reduces the number of separate template parameters that need to be considered, often improving readability; however, the preferred form is not supported on all platforms due to compiler bugs. The compatible form will work on all compilers supported by Boost.Function. Consult the table below to determine which syntactic form to use for your compiler. <p> Boost.Function has two syntactical forms: the preferred form and the compatibility form. The preferred form fits more closely with the C++ language and reduces the number of separate template parameters that need to be considered, often improving readability; however, the preferred form is not supported on all platforms due to compiler bugs. The compatible form will work on all compilers supported by Boost.Function. Consult the table below to determine which syntactic form to use for your compiler.
<center> <center>
<table border=1 cellspacing=1> <table border=1 cellspacing=1 summary="Compilers support for Boost.Function syntactic constructs">
<tr><th bgcolor="#008080">Preferred Syntax</th><th bgcolor="#008080">Compatible Syntax</th></tr> <tr><th bgcolor="#008080">Preferred Syntax</th><th bgcolor="#008080">Compatible Syntax</th></tr>
<tr> <tr>
<td> <td>
<ul> <ul>
<li>GNU C++ 2.95.x, 3.0.x, 3.1.x</li> <li>GNU C++ 2.95.x, 3.0.x, 3.1.x, 3.2</li>
<li>Comeau C++ 4.2.45.2</li> <li>Comeau C++ 4.2.45.2</li>
<li>SGI MIPSpro 7.3.0</li> <li>SGI MIPSpro 7.3.0</li>
<li>Intel C++ 5.0, 6.0</li> <li>Intel C++ 5.0, 6.0</li>
@ -37,10 +37,10 @@
<p> If your compiler does not appear in this list, please try the preferred syntax and report your results to the Boost list so that we can keep this table up-to-date. <p> If your compiler does not appear in this list, please try the preferred syntax and report your results to the Boost list so that we can keep this table up-to-date.
<a name="preferred"><h2>Basic Usage</h2></a> <h2><a name="preferred">Basic Usage</a></h2>
<p> A function wrapper is defined simply by instantiating the <code>function</code> class template with the desired return type and argument types, formulated as a C++ function type. Any number of arguments may be supplied, up to some implementation-defined limit (10 is the default maximum). The following declares a function object wrapper <code>f</code> that takes two <code>int</code> parameters and returns a <code>float</code>: <p> A function wrapper is defined simply by instantiating the <code>function</code> class template with the desired return type and argument types, formulated as a C++ function type. Any number of arguments may be supplied, up to some implementation-defined limit (10 is the default maximum). The following declares a function object wrapper <code>f</code> that takes two <code>int</code> parameters and returns a <code>float</code>:
<center> <center>
<table border=1 cellspacing=1> <table border=1 cellspacing=1 summary="Declaring Boost.Function objects">
<tr><th bgcolor="#008080">Preferred Syntax</th><th bgcolor="#008080">Compatible Syntax</th></tr> <tr><th bgcolor="#008080">Preferred Syntax</th><th bgcolor="#008080">Compatible Syntax</th></tr>
<tr> <tr>
<td> <td>
@ -77,7 +77,7 @@ std::cout &lt;&lt; f(5, 3) &gt;&gt; std::endl;
<p> We are free to assign any compatible function object to <code>f</code>. If <code>int_div</code> had been declared to take two <code>long</code> operands, <p> We are free to assign any compatible function object to <code>f</code>. If <code>int_div</code> had been declared to take two <code>long</code> operands,
the implicit conversions would have been applied to the arguments without any user interference. The only limit on the types of arguments is that they be CopyConstructible, so we can even use references and arrays: the implicit conversions would have been applied to the arguments without any user interference. The only limit on the types of arguments is that they be CopyConstructible, so we can even use references and arrays:
<center> <center>
<table border=1 cellspacing=1> <table border=1 cellspacing=1 summary="Declaring a more complex Boost.Function object">
<tr><th bgcolor="#008080">Preferred Syntax</th><th bgcolor="#008080">Compatible Syntax</th></tr> <tr><th bgcolor="#008080">Preferred Syntax</th><th bgcolor="#008080">Compatible Syntax</th></tr>
<tr> <tr>
<td> <td>
@ -95,7 +95,7 @@ boost::function4&lt;void, int[], int, int&amp;, float&gt; sum_avg;
</center> </center>
<pre> <pre>
void do_sum_avg(int values[], int n, int& sum, float&amp; avg) void do_sum_avg(int values[], int n, int&amp; sum, float&amp; avg)
{ {
sum = 0; sum = 0;
for (int i = 0; i &lt; n; i++) for (int i = 0; i &lt; n; i++)
@ -125,13 +125,12 @@ else
<p> Note that the <code>&amp;</code> isn't really necessary unless you happen to be using Microsoft Visual C++ version 6. <p> Note that the <code>&amp;</code> isn't really necessary unless you happen to be using Microsoft Visual C++ version 6.
<h3>Member functions</h3> <h3><a name="member_func">Member functions</a></h3>
<a name="member_func">
<p> In many systems, callbacks often call to member functions of a particular <p> In many systems, callbacks often call to member functions of a particular
object. This is often referred to as "argument binding", and is beyond the scope of Boost.Function. The use of member functions directly, however, is supported, so the following code is valid: object. This is often referred to as "argument binding", and is beyond the scope of Boost.Function. The use of member functions directly, however, is supported, so the following code is valid:
<center> <center>
<table border=1 cellspacing=1> <table border=1 cellspacing=1 summary="Member functions and Boost.Function">
<tr><th bgcolor="#008080">Preferred Syntax</th><th bgcolor="#008080">Compatible Syntax</th></tr> <tr><th bgcolor="#008080">Preferred Syntax</th><th bgcolor="#008080">Compatible Syntax</th></tr>
<tr> <tr>
<td> <td>
@ -172,7 +171,7 @@ f(&amp;x, 5);
<li> The C++ Standard library. Using <code>std::bind1st</code> and <code>std::mem_fun</code> together one can bind the object of a pointer-to-member function for use with Boost.Function: <li> The C++ Standard library. Using <code>std::bind1st</code> and <code>std::mem_fun</code> together one can bind the object of a pointer-to-member function for use with Boost.Function:
<center> <center>
<table border=1 cellspacing=1> <table border=1 cellspacing=1 summary="Boost.Bind and Boost.Function">
<tr><th bgcolor="#008080">Preferred Syntax</th><th bgcolor="#008080">Compatible Syntax</th></tr> <tr><th bgcolor="#008080">Preferred Syntax</th><th bgcolor="#008080">Compatible Syntax</th></tr>
<tr> <tr>
<td> <td>
@ -216,7 +215,7 @@ href="../../bind/ref.html"><code>ref</code></a> and <a
href="../../bind/ref.html"><code>cref</code></a> functions to wrap a href="../../bind/ref.html"><code>cref</code></a> functions to wrap a
reference to a function object: reference to a function object:
<center> <center>
<table border=1 cellspacing=1> <table border=1 cellspacing=1 summary="ref and cref with Boost.Function">
<tr><th bgcolor="#008080">Preferred Syntax</th><th bgcolor="#008080">Compatible Syntax</th></tr> <tr><th bgcolor="#008080">Preferred Syntax</th><th bgcolor="#008080">Compatible Syntax</th></tr>
<tr> <tr>
<td> <td>
@ -249,10 +248,10 @@ function objects, Boost.Function will not throw exceptions during
assignment or construction. assignment or construction.
<hr> <hr>
<address><a href="mailto:gregod@cs.rpi.edu">Douglas Gregor</a></address> <address><a href="http://www.cs.rpi.edu/~gregod">Doug Gregor</a></address>
<!-- Created: Fri Jul 13 12:47:11 EDT 2001 --> <!-- Created: Fri Jul 13 12:47:11 EDT 2001 -->
<!-- hhmts start --> <!-- hhmts start -->
Last modified: Mon Aug 5 11:07:17 EDT 2002 Last modified: Fri Oct 11 05:40:00 EDT 2002
<!-- hhmts end --> <!-- hhmts end -->
</body> </body>
</html> </html>

View File

@ -19,6 +19,15 @@
#ifndef BOOST_FUNCTION_HPP #ifndef BOOST_FUNCTION_HPP
#define BOOST_FUNCTION_HPP #define BOOST_FUNCTION_HPP
#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730
// Work around a compiler bug.
// boost::python::detail::function has to be seen by the compiler before the
// boost::function class template.
namespace boost { namespace python { namespace detail {
class function;
}}}
#endif
#include <boost/function/function_base.hpp> #include <boost/function/function_base.hpp>
#include <boost/type_traits/function_traits.hpp> #include <boost/type_traits/function_traits.hpp>
#include <boost/type_traits/same_traits.hpp> #include <boost/type_traits/same_traits.hpp>

View File

@ -6,7 +6,7 @@
<body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080"> <body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080">
<h1><IMG SRC="../../c++boost.gif" WIDTH="276" HEIGHT="86">Header &lt;<a HREF="../../boost/function.hpp">boost/function.hpp</a>&gt;</h1> <h1><IMG SRC="../../c++boost.gif" WIDTH="276" HEIGHT="86" alt="C++ Boost">Header &lt;<a HREF="../../boost/function.hpp">boost/function.hpp</a>&gt;</h1>
<p> The header &lt;<a HREF="../../boost/function.hpp">boost/function.hpp</a>&gt; includes a family of class templates that are function object wrappers. The notion is similar to a generalized callback. It shares features with function pointers in that both define a call interface (e.g., a function taking two integer arguments and returning a floating-point value) through which some implementation can be called, and the implementation that is invoked may change throughout the course of the program. <p> The header &lt;<a HREF="../../boost/function.hpp">boost/function.hpp</a>&gt; includes a family of class templates that are function object wrappers. The notion is similar to a generalized callback. It shares features with function pointers in that both define a call interface (e.g., a function taking two integer arguments and returning a floating-point value) through which some implementation can be called, and the implementation that is invoked may change throughout the course of the program.
@ -24,7 +24,7 @@
<li><a href="doc/faq.html">Frequently Asked Questions</a></li> <li><a href="doc/faq.html">Frequently Asked Questions</a></li>
</ul> </ul>
<a name="compatibility"><h2>Compatibility Note</h2></a> <h2><a name="compatibility">Compatibility Note</a></h2>
<p> Boost.Function has been partially redesigned to minimize the interface and make it cleaner. Several seldom- or never-used features of the older Boost.Function have been deprecated and will be removed in the near future. Here is a list of features that have been deprecated, the likely impact of the deprecations, and how to adjust your code: <p> Boost.Function has been partially redesigned to minimize the interface and make it cleaner. Several seldom- or never-used features of the older Boost.Function have been deprecated and will be removed in the near future. Here is a list of features that have been deprecated, the likely impact of the deprecations, and how to adjust your code:
<ul> <ul>
<li>The <code>boost::function</code> class template syntax has <li>The <code>boost::function</code> class template syntax has
@ -127,6 +127,6 @@ And, of course, function pointers have several advantages over Boost.Function:
<p> Many people were involved in the construction of this library. William Kempf, Jesse Jones and Karl Nelson were all extremely helpful in isolating an interface and scope for the library. John Maddock managed the formal review, and many reviewers gave excellent comments on interface, implementation, and documentation. <p> Many people were involved in the construction of this library. William Kempf, Jesse Jones and Karl Nelson were all extremely helpful in isolating an interface and scope for the library. John Maddock managed the formal review, and many reviewers gave excellent comments on interface, implementation, and documentation.
<hr> <hr>
<address><a href="mailto:gregod@cs.rpi.edu">Doug Gregor</a></address> <address><a href="http://www.cs.rpi.edu/~gregod">Doug Gregor</a></address>
</body> </body>
</html> </html>