mirror of
https://github.com/boostorg/lambda.git
synced 2026-01-21 17:02:36 +00:00
Compare commits
2 Commits
svn-branch
...
boost-1.30
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4fe0c9744c | ||
|
|
469741fa5c |
61
doc/apa.html
Normal file
61
doc/apa.html
Normal file
@@ -0,0 +1,61 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type"><title>A. Rationale for some of the design decisions</title><meta name="generator" content="DocBook XSL Stylesheets V1.48"><link rel="home" href="index.html" title="
|
||||
C++ BOOST
|
||||
|
||||
The Boost Lambda Library"><link rel="up" href="index.html" title="
|
||||
C++ BOOST
|
||||
|
||||
The Boost Lambda Library"><link rel="previous" href="ar01s09.html" title="9. Contributors"><link rel="next" href="bi01.html" title="Bibliography"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">A. Rationale for some of the design decisions</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ar01s09.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="bi01.html">Next</a></td></tr></table><hr></div><div class="appendix"><h2 class="title" style="clear: both"><a name="id2808823"></a>A. Rationale for some of the design decisions</h2><div class="section"><div class="titlepage"><div><h3 class="title"><a name="sect:why_weak_arity"></a>1.
|
||||
Lambda functor arity
|
||||
</h3></div></div><p>
|
||||
The highest placeholder index in a lambda expression determines the arity of the resulting function object.
|
||||
However, this is just the minimal arity, as the function object can take arbitrarily many arguments; those not needed are discarded.
|
||||
Consider the two bind expressions and their invocations below:
|
||||
|
||||
<pre class="programlisting">
|
||||
bind(g, _3, _3, _3)(x, y, z);
|
||||
bind(g, _1, _1, _1)(x, y, z);
|
||||
</pre>
|
||||
|
||||
This first line discards arguments <tt>x</tt> and
|
||||
<tt>y</tt>, and makes the call:
|
||||
<pre class="programlisting">
|
||||
g(z, z, z)
|
||||
</pre>
|
||||
whereas the second line discards arguments <tt>y</tt> and
|
||||
<tt>z</tt>, and calls:
|
||||
<pre class="programlisting">
|
||||
g(x, x, x)
|
||||
</pre>
|
||||
In earlier versions of the library, the latter line resulted in a compile
|
||||
time error.
|
||||
|
||||
This is basically a tradeoff between safety and flexibility, and the issue
|
||||
was extensively discussed during the Boost review period of the library.
|
||||
The main points for the <span class="emphasis"><i>strict arity</i></span> checking
|
||||
was that it might
|
||||
catch a programming error at an earlier time and that a lambda expression that
|
||||
explicitly discards its arguments is easy to write:
|
||||
<pre class="programlisting">
|
||||
(_3, bind(g, _1, _1, _1))(x, y, z);
|
||||
</pre>
|
||||
This lambda expression takes three arguments.
|
||||
The left-hand argument of the comma operator does nothing, and as comma
|
||||
returns the result of evaluating the right-hand argument we end up with
|
||||
the call
|
||||
<tt>g(x, x, x)</tt>
|
||||
even with the strict arity.
|
||||
</p><p>
|
||||
The main points against the strict arity checking were that the need to
|
||||
discard arguments is commonplace, and should therefore be straightforward,
|
||||
and that strict arity checking does not really buy that much more safety,
|
||||
particularly as it is not symmetric.
|
||||
For example, if the programmer wanted to write the expression
|
||||
<tt>_1 + _2</tt> but mistakenly wrote <tt>_1 + 2</tt>,
|
||||
with strict arity checking, the complier would spot the error.
|
||||
However, if the erroneous expression was <tt>1 + _2</tt> instead,
|
||||
the error would go unnoticed.
|
||||
Furthermore, weak arity checking simplifies the implementation a bit.
|
||||
Following the recommendation of the Boost review, strict arity checking
|
||||
was dropped.
|
||||
</p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ar01s09.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="bi01.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9. Contributors </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Bibliography</td></tr></table></div></body></html>
|
||||
57
doc/ar01s02.html
Normal file
57
doc/ar01s02.html
Normal file
@@ -0,0 +1,57 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type"><title>2. Getting Started</title><meta name="generator" content="DocBook XSL Stylesheets V1.48"><link rel="home" href="index.html" title="
|
||||
C++ BOOST
|
||||
|
||||
The Boost Lambda Library"><link rel="up" href="index.html" title="
|
||||
C++ BOOST
|
||||
|
||||
The Boost Lambda Library"><link rel="previous" href="index.html" title="
|
||||
C++ BOOST
|
||||
|
||||
The Boost Lambda Library"><link rel="next" href="ar01s03.html" title="3. Introduction"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">2. Getting Started</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="index.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ar01s03.html">Next</a></td></tr></table><hr></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="sect:getting_started"></a>2. Getting Started</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2790118"></a>2.1. Installing the library</h3></div></div><p>
|
||||
The library consists of include files only, hence there is no
|
||||
installation procedure. The <tt>boost</tt> include directory
|
||||
must be on the include path.
|
||||
There are a number of include files that give different functionality:
|
||||
|
||||
|
||||
<div class="itemizedlist"><ul type="disc"><li><p>
|
||||
<tt>lambda/lambda.hpp</tt> defines lambda expressions for different C++
|
||||
operators, see <a href="ar01s05.html#sect:operator_expressions" title="5.2. Operator expressions">Section 5.2</a>.
|
||||
</p></li><li><p>
|
||||
<tt>lambda/bind.hpp</tt> defines <tt>bind</tt> functions for up to 9 arguments, see <a href="ar01s05.html#sect:bind_expressions" title="5.3. Bind expressions">Section 5.3</a>.</p></li><li><p>
|
||||
<tt>lambda/if.hpp</tt> defines lambda function equivalents for if statements and the conditional operator, see <a href="ar01s05.html#sect:lambda_expressions_for_control_structures" title="5.6. Lambda expressions for control structures">Section 5.6</a> (includes <tt>lambda.hpp</tt>).
|
||||
</p></li><li><p>
|
||||
<tt>lambda/loops.hpp</tt> defines lambda function equivalent for looping constructs, see <a href="ar01s05.html#sect:lambda_expressions_for_control_structures" title="5.6. Lambda expressions for control structures">Section 5.6</a>.
|
||||
</p></li><li><p>
|
||||
<tt>lambda/switch.hpp</tt> defines lambda function equivalent for the switch statement, see <a href="ar01s05.html#sect:lambda_expressions_for_control_structures" title="5.6. Lambda expressions for control structures">Section 5.6</a>.
|
||||
</p></li><li><p>
|
||||
<tt>lambda/construct.hpp</tt> provides tools for writing lambda expressions with constructor, destructor, new and delete invocations, see <a href="ar01s05.html#sect:construction_and_destruction" title="5.8. Construction and destruction">Section 5.8</a> (includes <tt>lambda.hpp</tt>).
|
||||
</p></li><li><p>
|
||||
<tt>lambda/casts.hpp</tt> provides lambda versions of different casts, as well as <tt>sizeof</tt> and <tt>typeid</tt>, see <a href="ar01s05.html#sect:cast_expressions" title="5.10.1.
|
||||
Cast expressions
|
||||
">Section 5.10.1</a>.
|
||||
</p></li><li><p>
|
||||
<tt>lambda/exceptions.hpp</tt> gives tools for throwing and catching
|
||||
exceptions within lambda functions, <a href="ar01s05.html#sect:exceptions" title="5.7. Exceptions">Section 5.7</a> (includes
|
||||
<tt>lambda.hpp</tt>).
|
||||
</p></li><li><p>
|
||||
<tt>lambda/algorithm.hpp</tt> and <tt>lambda/numeric.hpp</tt> (cf. standard <tt>algortihm</tt> and <tt>numeric</tt> headers) allow nested STL algorithm invocations, see <a href="ar01s05.html#sect:nested_stl_algorithms" title="5.11. Nesting STL algorithm invocations">Section 5.11</a>.
|
||||
</p></li></ul></div>
|
||||
|
||||
Any other header files in the package are for internal use.
|
||||
Additionally, the library depends on two other Boost Libraries, the
|
||||
<span class="emphasis"><i>Tuple</i></span> [<a href="bi01.html#cit:boost::tuple" title="[tuple]">tuple</a>] and the <span class="emphasis"><i>type_traits</i></span> [<a href="bi01.html#cit:boost::type_traits" title="[type_traits]">type_traits</a>] libraries, and on the <tt>boost/ref.hpp</tt> header.
|
||||
</p><p>
|
||||
All definitions are placed in the namespace <tt>boost::lambda</tt> and its subnamespaces.
|
||||
</p></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2741945"></a>2.2. Conventions used in this document</h3></div></div><p>In most code examples, we omit the namespace prefixes for names in the <tt>std</tt> and <tt>boost::lambda</tt> namespaces.
|
||||
Implicit using declarations
|
||||
<pre class="programlisting">
|
||||
using namespace std;
|
||||
using namespace boost::lambda;
|
||||
</pre>
|
||||
are assumed to be in effect.
|
||||
</p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="index.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ar01s03.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">
|
||||
C++ BOOST
|
||||
|
||||
The Boost Lambda Library </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 3. Introduction</td></tr></table></div></body></html>
|
||||
175
doc/ar01s03.html
Normal file
175
doc/ar01s03.html
Normal file
@@ -0,0 +1,175 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type"><title>3. Introduction</title><meta name="generator" content="DocBook XSL Stylesheets V1.48"><link rel="home" href="index.html" title="
|
||||
C++ BOOST
|
||||
|
||||
The Boost Lambda Library"><link rel="up" href="index.html" title="
|
||||
C++ BOOST
|
||||
|
||||
The Boost Lambda Library"><link rel="previous" href="ar01s02.html" title="2. Getting Started"><link rel="next" href="ar01s04.html" title="4. Using the library"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">3. Introduction</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ar01s02.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ar01s04.html">Next</a></td></tr></table><hr></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="id2741991"></a>3. Introduction</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2741999"></a>3.1. Motivation</h3></div></div><p>The Standard Template Library (STL)
|
||||
[<a href="bi01.html#cit:stepanov:94" title="[STL94]">STL94</a>], now part of the C++ Standard Library [<a href="bi01.html#cit:c++:98" title="[C++98]">C++98</a>], is a generic container and algorithm library.
|
||||
Typically STL algorithms operate on container elements via <span class="emphasis"><i>function objects</i></span>. These function objects are passed as arguments to the algorithms.
|
||||
</p><p>
|
||||
Any C++ construct that can be called with the function call syntax
|
||||
is a function object.
|
||||
The STL contains predefined function objects for some common cases (such as <tt>plus</tt>, <tt>less</tt> and <tt>not1</tt>).
|
||||
As an example, one possible implementation for the standard <tt>plus</tt> template is:
|
||||
|
||||
<pre class="programlisting">
|
||||
template <class T> : public binary_function<T, T, T>
|
||||
struct plus {
|
||||
T operator()(const T& i, const T& j) const {
|
||||
return i + j;
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
|
||||
The base class <tt>binary_function<T, T, T></tt> contains typedefs for the argument and return types of the function object, which are needed to make the function object <span class="emphasis"><i>adaptable</i></span>.
|
||||
</p><p>
|
||||
In addition to the basic function object classes, such as the one above,
|
||||
the STL contains <span class="emphasis"><i>binder</i></span> templates for creating a unary function object from an adaptable binary function object by fixing one of the arguments to a constant value.
|
||||
For example, instead of having to explicitly write a function object class like:
|
||||
|
||||
<pre class="programlisting">
|
||||
class plus_1 {
|
||||
int _i;
|
||||
public:
|
||||
plus_1(const int& i) : _i(i) {}
|
||||
int operator()(const int& j) { return _i + j; }
|
||||
};
|
||||
</pre>
|
||||
|
||||
the equivalent functionality can be achieved with the <tt>plus</tt> template and one of the binder templates (<tt>bind1st</tt>).
|
||||
E.g., the following two expressions create function objects with identical functionalities;
|
||||
when invoked, both return the result of adding <tt>1</tt> to the argument of the function object:
|
||||
|
||||
<pre class="programlisting">
|
||||
plus_1(1)
|
||||
bind1st(plus<int>(), 1)
|
||||
</pre>
|
||||
|
||||
The subexpression <tt>plus<int>()</tt> in the latter line is a binary function object which computes the sum of two integers, and <tt>bind1st</tt> invokes this function object partially binding the first argument to <tt>1</tt>.
|
||||
As an example of using the above function object, the following code adds <tt>1</tt> to each element of some container <tt>a</tt> and outputs the results into the standard output stream <tt>cout</tt>.
|
||||
|
||||
<pre class="programlisting">
|
||||
transform(a.begin(), a.end(), ostream_iterator<int>(cout),
|
||||
bind1st(plus<int>(), 1));
|
||||
</pre>
|
||||
|
||||
</p><p>
|
||||
To make the binder templates more generally applicable, the STL contains <span class="emphasis"><i>adaptors</i></span> for making
|
||||
pointers or references to functions, and pointers to member functions,
|
||||
adaptable.
|
||||
|
||||
Finally, some STL implementations contain function composition operations as
|
||||
extensions to the standard [<a href="bi01.html#cit:sgi:02" title="[SGI02]">SGI02</a>].
|
||||
</p><p>
|
||||
All these tools aim at one goal: to make it possible to specify
|
||||
<span class="emphasis"><i>unnamed functions</i></span> in a call of an STL algorithm,
|
||||
in other words, to pass code fragments as an argument to a function.
|
||||
|
||||
However, this goal is attained only partially.
|
||||
The simple example above shows that the definition of unnamed functions
|
||||
with the standard tools is cumbersome.
|
||||
|
||||
Complex expressions involving functors, adaptors, binders and
|
||||
function composition operations tend to be difficult to comprehend.
|
||||
|
||||
In addition to this, there are significant restrictions in applying
|
||||
the standard tools. E.g. the standard binders allow only one argument
|
||||
of a binary function to be bound; there are no binders for
|
||||
3-ary, 4-ary etc. functions.
|
||||
</p><p>
|
||||
The Boost Lambda Library provides solutions for the problems described above:
|
||||
|
||||
<div class="itemizedlist"><ul type="disc"><li><p>
|
||||
Unnamed functions can be created easily with an intuitive syntax.
|
||||
|
||||
The above example can be written as:
|
||||
|
||||
<pre class="programlisting">
|
||||
transform(a.begin(), a.end(), ostream_iterator<int>(cout),
|
||||
1 + _1);
|
||||
</pre>
|
||||
|
||||
or even more intuitively:
|
||||
|
||||
<pre class="programlisting">
|
||||
for_each(a.begin(), a.end(), cout << (1 + _1));
|
||||
</pre>
|
||||
</p></li><li><p>
|
||||
Most of the restrictions in argument binding are removed,
|
||||
arbitrary arguments of practically any C++ function can be bound.
|
||||
</p></li><li><p>
|
||||
Separate function composition operations are not needed,
|
||||
as function composition is supported implicitly.
|
||||
|
||||
</p></li></ul></div>
|
||||
|
||||
</p></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2742792"></a>3.2. Introduction to lambda expressions</h3></div></div><p>
|
||||
Lambda expression are common in functional programming languages.
|
||||
Their syntax varies between languages (and between different forms of lambda calculus), but the basic form of a lambda expressions is:
|
||||
|
||||
|
||||
<pre class="programlisting">
|
||||
lambda x<sub>1</sub> ... x<sub>n</sub>.e
|
||||
</pre>
|
||||
|
||||
|
||||
A lambda expression defines an unnamed function and consists of:
|
||||
<div class="itemizedlist"><ul type="disc"><li><p>
|
||||
the parameters of this function: <tt>x<sub>1</sub> ... x<sub>n</sub></tt>.
|
||||
|
||||
</p></li><li><p>the expression e which computes the value of the function in terms of the parameters <tt>x<sub>1</sub> ... x<sub>n</sub></tt>.
|
||||
</p></li></ul></div>
|
||||
|
||||
A simple example of a lambda expression is
|
||||
<pre class="programlisting">
|
||||
lambda x y.x+y
|
||||
</pre>
|
||||
Applying the lambda function means substituting the formal parameters with the actual arguments:
|
||||
<pre class="programlisting">
|
||||
(lambda x y.x+y) 2 3 = 2 + 3 = 5
|
||||
</pre>
|
||||
|
||||
|
||||
</p><p>
|
||||
In the C++ version of lambda expressions the <tt>lambda x<sub>1</sub> ... x<sub>n</sub></tt> part is missing and the formal parameters have predefined names.
|
||||
In the current version of the library,
|
||||
there are three such predefined formal parameters,
|
||||
called <span class="emphasis"><i>placeholders</i></span>:
|
||||
<tt>_1</tt>, <tt>_2</tt> and <tt>_3</tt>.
|
||||
They refer to the first, second and third argument of the function defined
|
||||
by the lambda expression.
|
||||
|
||||
For example, the C++ version of the definition
|
||||
<pre class="programlisting">lambda x y.x+y</pre>
|
||||
is
|
||||
<pre class="programlisting">_1 + _2</pre>
|
||||
</p><p>
|
||||
Hence, there is no syntactic keyword for C++ lambda expressions.
|
||||
The use of a placeholder as an operand implies that the operator invocation is a lambda expression.
|
||||
However, this is true only for operator invocations.
|
||||
Lambda expressions containing function calls, control structures, casts etc. require special syntactic constructs.
|
||||
Most importantly, function calls need to be wrapped inside a <tt>bind</tt> function.
|
||||
|
||||
As an example, consider the lambda expression:
|
||||
|
||||
<pre class="programlisting">lambda x y.foo(x,y)</pre>
|
||||
|
||||
Rather than <tt>foo(_1, _2)</tt>, the C++ counterpart for this expression is:
|
||||
|
||||
<pre class="programlisting">bind(foo, _1, _2)</pre>
|
||||
|
||||
We refer to this type of C++ lambda expressions as <span class="emphasis"><i>bind expressions</i></span>.
|
||||
</p><p>A lambda expression defines a C++ function object, hence function application syntax is like calling any other function object, for instance: <tt>(_1 + _2)(i, j)</tt>.
|
||||
|
||||
|
||||
</p><div class="section"><div class="titlepage"><div><h4 class="title"><a name="sect:partial_function_application"></a>3.2.1. Partial function application</h4></div></div><p>
|
||||
A bind expression is in effect a <span class="emphasis"><i>partial function application</i></span>.
|
||||
In partial function application, some of the arguments of a function are bound to fixed values.
|
||||
The result is another function, with possibly fewer arguments.
|
||||
When called with the unbound arguments, this new function invokes the original function with the merged argument list of bound and unbound arguments.
|
||||
</p></div><div class="section"><div class="titlepage"><div><h4 class="title"><a name="sect:terminology"></a>3.2.2. Terminology</h4></div></div><p>
|
||||
A lambda expression defines a function. A C++ lambda expression concretely constructs a function object, <span class="emphasis"><i>a functor</i></span>, when evaluated. We use the name <span class="emphasis"><i>lambda functor</i></span> to refer to such a function object.
|
||||
Hence, in the terminology adopted here, the result of evaluating a lambda expression is a lambda functor.
|
||||
</p></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ar01s02.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ar01s04.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">2. Getting Started </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 4. Using the library</td></tr></table></div></body></html>
|
||||
213
doc/ar01s04.html
Normal file
213
doc/ar01s04.html
Normal file
@@ -0,0 +1,213 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type"><title>4. Using the library</title><meta name="generator" content="DocBook XSL Stylesheets V1.48"><link rel="home" href="index.html" title="
|
||||
C++ BOOST
|
||||
|
||||
The Boost Lambda Library"><link rel="up" href="index.html" title="
|
||||
C++ BOOST
|
||||
|
||||
The Boost Lambda Library"><link rel="previous" href="ar01s03.html" title="3. Introduction"><link rel="next" href="ar01s05.html" title="5. Lambda expressions in details"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">4. Using the library</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ar01s03.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ar01s05.html">Next</a></td></tr></table><hr></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="sect:using_library"></a>4. Using the library</h2></div></div><p>
|
||||
The purpose of this section is to introduce the basic functionality of the library.
|
||||
There are quite a lot of exceptions and special cases, but discussion of them is postponed until later sections.
|
||||
|
||||
|
||||
</p><div class="section"><div class="titlepage"><div><h3 class="title"><a name="sect:introductory_examples"></a>4.1. Introductory Examples</h3></div></div><p>
|
||||
In this section we give basic examples of using BLL lambda expressions in STL algorithm invocations.
|
||||
We start with some simple expressions and work up.
|
||||
First, we initialize the elements of a container, say, a <tt>list</tt>, to the value <tt>1</tt>:
|
||||
|
||||
|
||||
<pre class="programlisting">
|
||||
list<int> v(10);
|
||||
for_each(v.begin(), v.end(), _1 = 1);</pre>
|
||||
|
||||
The expression <tt>_1 = 1</tt> creates a lambda functor which assigns the value <tt>1</tt> to every element in <tt>v</tt>.<sup>[<a name="id2739596" href="#ftn.id2739596">1</a>]</sup>
|
||||
</p><p>
|
||||
Next, we create a container of pointers and make them point to the elements in the first container <tt>v</tt>:
|
||||
|
||||
<pre class="programlisting">
|
||||
vector<int*> vp(10);
|
||||
transform(v.begin(), v.end(), vp.begin(), &_1);</pre>
|
||||
|
||||
The expression <tt>&_1</tt> creates a function object for getting the address of each element in <tt>v</tt>.
|
||||
The addresses get assigned to the corresponding elements in <tt>vp</tt>.
|
||||
</p><p>
|
||||
The next code fragment changes the values in <tt>v</tt>.
|
||||
For each element, the function <tt>foo</tt> is called.
|
||||
The original value of the element is passed as an argument to <tt>foo</tt>.
|
||||
The result of <tt>foo</tt> is assigned back to the element:
|
||||
|
||||
|
||||
<pre class="programlisting">
|
||||
int foo(int);
|
||||
for_each(v.begin(), v.end(), _1 = bind(foo, _1));</pre>
|
||||
</p><p>
|
||||
The next step is to sort the elements of <tt>vp</tt>:
|
||||
|
||||
<pre class="programlisting">sort(vp.begin(), vp.end(), *_1 > *_2);</pre>
|
||||
|
||||
In this call to <tt>sort</tt>, we are sorting the elements by their contents in descending order.
|
||||
</p><p>
|
||||
Finally, the following <tt>for_each</tt> call outputs the sorted content of <tt>vp</tt> separated by line breaks:
|
||||
|
||||
<pre class="programlisting">
|
||||
for_each(vp.begin(), vp.end(), cout << *_1 << '\n');
|
||||
</pre>
|
||||
|
||||
Note that a normal (non-lambda) expression as subexpression of a lambda expression is evaluated immediately.
|
||||
This may cause surprises.
|
||||
For instance, if the previous example is rewritten as
|
||||
<pre class="programlisting">
|
||||
for_each(vp.begin(), vp.end(), cout << '\n' << *_1);
|
||||
</pre>
|
||||
the subexpression <tt>cout << '\n'</tt> is evaluated immediately and the effect is to output a single line break, followed by the elements of <tt>vp</tt>.
|
||||
The BLL provides functions <tt>constant</tt> and <tt>var</tt> to turn constants and, respectively, variables into lambda expressions, and can be used to prevent the immediate evaluation of subexpressions:
|
||||
<pre class="programlisting">
|
||||
for_each(vp.begin(), vp.end(), cout << constant('\n') << *_1);
|
||||
</pre>
|
||||
These functions are described more thoroughly in <a href="ar01s05.html#sect:delaying_constants_and_variables" title="5.5. Delaying constants and variables">Section 5.5</a>
|
||||
|
||||
</p></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="sect:parameter_and_return_types"></a>4.2. Parameter and return types of lambda functors</h3></div></div><p>
|
||||
During the invocation of a lambda functor, the actual arguments are substituted for the placeholders.
|
||||
The placeholders do not dictate the type of these actual arguments.
|
||||
The basic rule is that a lambda function can be called with arguments of any types, as long as the lambda expression with substitutions performed is a valid C++ expression.
|
||||
As an example, the expression
|
||||
<tt>_1 + _2</tt> creates a binary lambda functor.
|
||||
It can be called with two objects of any types <tt>A</tt> and <tt>B</tt> for which <tt>operator+(A,B)</tt> is defined (and for which BLL knows the return type of the operator, see below).
|
||||
</p><p>
|
||||
C++ lacks a mechanism to query a type of an expression.
|
||||
However, this precise mechanism is crucial for the implementation of C++ lambda expressions.
|
||||
Consequently, BLL includes a somewhat complex type deduction system which uses a set of traits classes for deducing the resulting type of lambda functions.
|
||||
It handles expressions where the operands are of built-in types and many of the expressions with operands of standard library types.
|
||||
Many of the user defined types are covered as well, particularly if the user defined operators obey normal conventions in defining the return types.
|
||||
</p><p>
|
||||
There are, however, cases when the return type cannot be deduced. For example, suppose you have defined:
|
||||
|
||||
<pre class="programlisting">C operator+(A, B);</pre>
|
||||
|
||||
The following lambda function invocation fails, since the return type cannot be deduced:
|
||||
|
||||
<pre class="programlisting">A a; B b; (_1 + _2)(a, b);</pre>
|
||||
</p><p>
|
||||
There are two alternative solutions to this.
|
||||
The first is to extend the BLL type deduction system to cover your own types (see <a href="ar01s06.html#sect:extending_return_type_system" title="6. Extending return type deduction system">Section 6</a>).
|
||||
The second is to use a special lambda expression (<tt>ret</tt>) which defines the return type in place (see <a href="ar01s05.html#sect:overriding_deduced_return_type" title="5.4. Overriding the deduced return type">Section 5.4</a>):
|
||||
|
||||
<pre class="programlisting">A a; B b; ret<C>(_1 + _2)(a, b);</pre>
|
||||
</p><p>
|
||||
For bind expressions, the return type can be defined as a template argument of the bind function as well:
|
||||
<pre class="programlisting">bind<int>(foo, _1, _2);</pre>
|
||||
|
||||
|
||||
</p></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="sect:actual_arguments_to_lambda_functors"></a>4.3. About actual arguments to lambda functors</h3></div></div><p>A general restriction for the actual arguments is that they cannot be non-const rvalues.
|
||||
For example:
|
||||
|
||||
<pre class="programlisting">
|
||||
int i = 1; int j = 2;
|
||||
(_1 + _2)(i, j); // ok
|
||||
(_1 + _2)(1, 2); // error (!)
|
||||
</pre>
|
||||
|
||||
This restriction is not as bad as it may look.
|
||||
Since the lambda functors are most often called inside STL-algorithms,
|
||||
the arguments originate from dereferencing iterators and the dereferencing operators seldom return rvalues.
|
||||
And for the cases where they do, there are workarounds discussed in
|
||||
<a href="ar01s05.html#sect:rvalues_as_actual_arguments" title="5.9.2. Rvalues as actual arguments to lambda functors">Section 5.9.2</a>.
|
||||
|
||||
|
||||
</p></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="sect:storing_bound_arguments"></a>4.4. Storing bound arguments in lambda functions</h3></div></div><p>
|
||||
|
||||
By default, temporary const copies of the bound arguments are stored
|
||||
in the lambda functor.
|
||||
|
||||
This means that the value of a bound argument is fixed at the time of the
|
||||
creation of the lambda function and remains constant during the lifetime
|
||||
of the lambda function object.
|
||||
|
||||
For example:
|
||||
|
||||
<pre class="programlisting">
|
||||
int i = 1;
|
||||
(_1 + i)(i = 2);
|
||||
</pre>
|
||||
|
||||
The value of the expression in the last line is 3, not 4.
|
||||
|
||||
In other words, the lambda expression <tt>_1 + i</tt> creates
|
||||
a lambda function <tt>lambda x.x+1</tt> rather than
|
||||
<tt>lambda x.x+i</tt>.
|
||||
|
||||
</p><p>
|
||||
|
||||
As said, this is the default behavior for which there are exceptions.
|
||||
The exact rules are as follows:
|
||||
|
||||
<div class="itemizedlist"><ul type="disc"><li><p>
|
||||
|
||||
The programmer can control the storing mechanism with <tt>ref</tt>
|
||||
and <tt>cref</tt> wrappers [<a href="bi01.html#cit:boost::ref" title="[ref]">ref</a>].
|
||||
|
||||
Wrapping an argument with <tt>ref</tt>, or <tt>cref</tt>,
|
||||
instructs the library to store the argument as a reference,
|
||||
or as a reference to const respectively.
|
||||
|
||||
For example, if we rewrite the previous example and wrap the variable
|
||||
<tt>i</tt> with <tt>ref</tt>,
|
||||
we are creating the lambda expression <tt>lambda x.x+i</tt>
|
||||
and the value of the expression in the last line will be 4:
|
||||
|
||||
<pre class="programlisting">
|
||||
i = 1;
|
||||
(_1 + ref(i))(i = 2);
|
||||
</pre>
|
||||
|
||||
Note that <tt>ref</tt> and <tt>cref</tt> are different
|
||||
from <tt>var</tt> and <tt>constant</tt>.
|
||||
|
||||
While the latter ones create lambda functors, the former do not.
|
||||
For example:
|
||||
|
||||
<pre class="programlisting">
|
||||
int i;
|
||||
var(i) = 1; // ok
|
||||
ref(i) = 1; // not ok, ref(i) is not a lambda functor
|
||||
</pre>
|
||||
|
||||
The functions <tt>ref</tt> and <tt>cref</tt> mostly
|
||||
exist for historical reasons,
|
||||
and <tt>ref</tt> can always
|
||||
be replaced with <tt>var</tt>, and <tt>cref</tt> with
|
||||
<tt>constant_ref</tt>.
|
||||
See <a href="ar01s05.html#sect:delaying_constants_and_variables" title="5.5. Delaying constants and variables">Section 5.5</a> for details.
|
||||
The <tt>ref</tt> and <tt>cref</tt> functions are
|
||||
general purpose utility functions in Boost, and hence defined directly
|
||||
in the <tt>boost</tt> namespace.
|
||||
|
||||
</p></li><li><p>
|
||||
Array types cannot be copied, they are thus stored as const reference by default.
|
||||
</p></li><li><p>
|
||||
For some expressions it makes more sense to store the arguments as references.
|
||||
|
||||
For example, the obvious intention of the lambda expression
|
||||
<tt>i += _1</tt> is that calls to the lambda functor affect the
|
||||
value of the variable <tt>i</tt>,
|
||||
rather than some temporary copy of it.
|
||||
|
||||
As another example, the streaming operators take their leftmost argument
|
||||
as non-const references.
|
||||
|
||||
The exact rules are:
|
||||
|
||||
<div class="itemizedlist"><ul type="round"><li><p>The left argument of compound assignment operators (<tt>+=</tt>, <tt>*=</tt>, etc.) are stored as references to non-const.</p></li><li><p>If the left argument of <tt><<</tt> or <tt>>></tt> operator is derived from an instantiation of <tt>basic_ostream</tt> or respectively from <tt>basic_istream</tt>, the argument is stored as a reference to non-const.
|
||||
For all other types, the argument is stored as a copy.
|
||||
</p></li><li><p>
|
||||
In pointer arithmetic expressions, non-const array types are stored as non-const references.
|
||||
This is to prevent pointer arithmetic making non-const arrays const.
|
||||
|
||||
</p></li></ul></div>
|
||||
|
||||
</p></li></ul></div>
|
||||
</p></div><div class="footnotes"><br><hr width="100" align="left"><div class="footnote"><p><sup>[<a name="ftn.id2739596" href="#id2739596">1</a>] </sup>
|
||||
Strictly taken, the C++ standard defines <tt>for_each</tt> as a <span class="emphasis"><i>non-modifying sequence operation</i></span>, and the function object passed to <tt>for_each</tt> should not modify its argument.
|
||||
The requirements for the arguments of <tt>for_each</tt> are unnecessary strict, since as long as the iterators are <span class="emphasis"><i>mutable</i></span>, <tt>for_each</tt> accepts a function object that can have side-effects on their argument.
|
||||
Nevertheless, it is straightforward to provide another function template with the functionality of<tt>std::for_each</tt> but more fine-grained requirements for its arguments.
|
||||
</p></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ar01s03.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ar01s05.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">3. Introduction </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 5. Lambda expressions in details</td></tr></table></div></body></html>
|
||||
1187
doc/ar01s05.html
Normal file
1187
doc/ar01s05.html
Normal file
File diff suppressed because it is too large
Load Diff
207
doc/ar01s06.html
Normal file
207
doc/ar01s06.html
Normal file
@@ -0,0 +1,207 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type"><title>6. Extending return type deduction system</title><meta name="generator" content="DocBook XSL Stylesheets V1.48"><link rel="home" href="index.html" title="
|
||||
C++ BOOST
|
||||
|
||||
The Boost Lambda Library"><link rel="up" href="index.html" title="
|
||||
C++ BOOST
|
||||
|
||||
The Boost Lambda Library"><link rel="previous" href="ar01s05.html" title="5. Lambda expressions in details"><link rel="next" href="ar01s07.html" title="7. Practical considerations"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">6. Extending return type deduction system</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ar01s05.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ar01s07.html">Next</a></td></tr></table><hr></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="sect:extending_return_type_system"></a>6. Extending return type deduction system</h2></div></div><p>
|
||||
|
||||
|
||||
In this section, we explain how to extend the return type deduction system
|
||||
to cover user defined operators.
|
||||
|
||||
In many cases this is not necessary,
|
||||
as the BLL defines default return types for operators.
|
||||
|
||||
For example, the default return type for all comparison operators is
|
||||
<tt>bool</tt>, and as long as the user defined comparison operators
|
||||
have a bool return type, there is no need to write new specializations
|
||||
for the return type deduction classes.
|
||||
|
||||
Sometimes this cannot be avoided, though.
|
||||
|
||||
</p><p>
|
||||
The overloadable user defined operators are either unary or binary.
|
||||
|
||||
For each arity, there are two traits templates that define the
|
||||
return types of the different operators.
|
||||
|
||||
Hence, the return type system can be extended by providing more
|
||||
specializations for these templates.
|
||||
|
||||
The templates for unary functors are
|
||||
|
||||
<tt>
|
||||
plain_return_type_1<Action, A>
|
||||
</tt>
|
||||
|
||||
and
|
||||
|
||||
<tt>
|
||||
return_type_1<Action, A>
|
||||
</tt>, and
|
||||
|
||||
<tt>
|
||||
plain_return_type_2<Action, A, B>
|
||||
</tt>
|
||||
|
||||
and
|
||||
|
||||
<tt>
|
||||
return_type_2<Action, A, B>
|
||||
</tt>
|
||||
|
||||
respectively for binary functors.
|
||||
|
||||
</p><p>
|
||||
The first parameter (<tt>Action</tt>) to all these templates
|
||||
is the <span class="emphasis"><i>action</i></span> class, which specifies the operator.
|
||||
|
||||
Operators with similar return type rules are grouped together into
|
||||
<span class="emphasis"><i>action groups</i></span>,
|
||||
and only the action class and action group together define the operator
|
||||
unambiguously.
|
||||
|
||||
As an example, the action type
|
||||
<tt>arithmetic_action<plus_action></tt> stands for
|
||||
<tt>operator+</tt>.
|
||||
|
||||
The complete listing of different action types is shown in
|
||||
<a href="ar01s06.html#table:actions" title="Table 2. Action types">Table 2</a>.
|
||||
</p><p>
|
||||
The latter parameters, <tt>A</tt> in the unary case,
|
||||
or <tt>A</tt> and <tt>B</tt> in the binary case,
|
||||
stand for the argument types of the operator call.
|
||||
|
||||
The two sets of templates,
|
||||
<tt>plain_return_type_<i><tt>n</tt></i></tt> and
|
||||
<tt>return_type_<i><tt>n</tt></i></tt>
|
||||
(<i><tt>n</tt></i> is 1 or 2) differ in the way how parameter types
|
||||
are presented to them.
|
||||
|
||||
For the former templates, the parameter types are always provided as
|
||||
non-reference types, and do not have const or volatile qualifiers.
|
||||
|
||||
This makes specializing easy, as commonly one specialization for each
|
||||
user defined operator, or operator group, is enough.
|
||||
|
||||
On the other hand, if a particular operator is overloaded for different
|
||||
cv-qualifications of the same argument types,
|
||||
and the return types of these overloaded versions differ, a more fine-grained control is needed.
|
||||
|
||||
Hence, for the latter templates, the parameter types preserve the
|
||||
cv-qualifiers, and are non-reference types as well.
|
||||
|
||||
The downside is, that for an overloaded set of operators of the
|
||||
kind described above, one may end up needing up to
|
||||
16 <tt>return_type_2</tt> specializations.
|
||||
</p><p>
|
||||
Suppose the user has overloaded the following operators for some user defined
|
||||
types <tt>X</tt>, <tt>Y</tt> and <tt>Z</tt>:
|
||||
|
||||
<pre class="programlisting">
|
||||
Z operator+(const X&, const Y&);
|
||||
Z operator-(const X&, const Y&);
|
||||
</pre>
|
||||
|
||||
Now, one can add a specialization stating, that if the left hand argument
|
||||
is of type <tt>X</tt>, and the right hand one of type
|
||||
<tt>Y</tt>, the return type of all such binary arithmetic
|
||||
operators is <tt>Z</tt>:
|
||||
|
||||
<pre class="programlisting">
|
||||
namespace boost {
|
||||
namespace lambda {
|
||||
|
||||
template<class Act>
|
||||
struct plain_return_type_2<arithmetic_action<Act>, X, Y> {
|
||||
typedef Z type;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
Having this specialization defined, BLL is capable of correctly
|
||||
deducing the return type of the above two operators.
|
||||
|
||||
Note, that the specializations must be in the same namespace,
|
||||
<tt>::boost::lambda</tt>, with the primary template.
|
||||
|
||||
For brevity, we do not show the namespace definitions in the examples below.
|
||||
</p><p>
|
||||
It is possible to specialize on the level of an individual operator as well,
|
||||
in addition to providing a specialization for a group of operators.
|
||||
Say, we add a new arithmetic operator for argument types <tt>X</tt>
|
||||
and <tt>Y</tt>:
|
||||
|
||||
<pre class="programlisting">
|
||||
X operator*(const X&, const Y&);
|
||||
</pre>
|
||||
|
||||
Our first rule for all arithmetic operators specifies that the return
|
||||
type of this operator is <tt>Z</tt>,
|
||||
which obviously is not the case.
|
||||
Hence, we provide a new rule for the multiplication operator:
|
||||
|
||||
<pre class="programlisting">
|
||||
template<>
|
||||
struct plain_return_type_2<arithmetic_action<multiply_action>, X, Y> {
|
||||
typedef X type;
|
||||
};
|
||||
</pre>
|
||||
</p><p>
|
||||
The specializations can define arbitrary mappings from the argument types
|
||||
to the return type.
|
||||
|
||||
Suppose we have some mathematical vector type, templated on the element type:
|
||||
|
||||
<pre class="programlisting">
|
||||
template <class T> class my_vector;
|
||||
</pre>
|
||||
|
||||
Suppose the addition operator is defined between any two
|
||||
<tt>my_vector</tt> instantiations,
|
||||
as long as the addition operator is defined between their element types.
|
||||
|
||||
Furthermore, the element type of the resulting <tt>my_vector</tt>
|
||||
is the same as the result type of the addition between the element types.
|
||||
|
||||
E.g., adding <tt>my_vector<int></tt> and
|
||||
<tt>my_vector<double></tt> results in
|
||||
<tt>my_vector<double></tt>.
|
||||
|
||||
The BLL has traits classes to perform the implicit built-in and standard
|
||||
type conversions between integral, floating point, and complex classes.
|
||||
|
||||
Using BLL tools, the addition operator described above can be defined as:
|
||||
|
||||
<pre class="programlisting">
|
||||
template<class A, class B>
|
||||
my_vector<typename return_type_2<arithmetic_action<plus_action>, A, B>::type>
|
||||
operator+(const my_vector<A>& a, const my_vector<B>& b)
|
||||
{
|
||||
typedef typename
|
||||
return_type_2<arithmetic_action<plus_action>, A, B>::type res_type;
|
||||
return my_vector<res_type>();
|
||||
}
|
||||
</pre>
|
||||
</p><p>
|
||||
To allow BLL to deduce the type of <tt>my_vector</tt>
|
||||
additions correctly, we can define:
|
||||
|
||||
<pre class="programlisting">
|
||||
template<class A, class B>
|
||||
class plain_return_type_2<arithmetic_action<plus_action>,
|
||||
my_vector<A>, my_vector<B> > {
|
||||
typedef typename
|
||||
return_type_2<arithmetic_action<plus_action>, A, B>::type res_type;
|
||||
public:
|
||||
typedef my_vector<res_type> type;
|
||||
};
|
||||
</pre>
|
||||
Note, that we are reusing the existing specializations for the
|
||||
BLL <tt>return_type_2</tt> template,
|
||||
which require that the argument types are references.
|
||||
</p><div class="table"><p><a name="table:actions"></a><b>Table 2. Action types</b></p><table summary="Action types" border="1"><colgroup><col><col></colgroup><tbody><tr><td><tt>+</tt></td><td><tt>arithmetic_action<plus_action></tt></td></tr><tr><td><tt>-</tt></td><td><tt>arithmetic_action<minus_action></tt></td></tr><tr><td><tt>*</tt></td><td><tt>arithmetic_action<multiply_action></tt></td></tr><tr><td><tt>/</tt></td><td><tt>arithmetic_action<divide_action></tt></td></tr><tr><td><tt>%</tt></td><td><tt>arithmetic_action<remainder_action></tt></td></tr><tr><td><tt>+</tt></td><td><tt>unary_arithmetic_action<plus_action></tt></td></tr><tr><td><tt>-</tt></td><td><tt>unary_arithmetic_action<minus_action></tt></td></tr><tr><td><tt>&</tt></td><td><tt>bitwise_action<and_action></tt></td></tr><tr><td><tt>|</tt></td><td><tt>bitwise_action<or_action></tt></td></tr><tr><td><tt>~</tt></td><td><tt>bitwise_action<not_action></tt></td></tr><tr><td><tt>^</tt></td><td><tt>bitwise_action<xor_action></tt></td></tr><tr><td><tt><<</tt></td><td><tt>bitwise_action<leftshift_action_no_stream></tt></td></tr><tr><td><tt>>></tt></td><td><tt>bitwise_action<rightshift_action_no_stream></tt></td></tr><tr><td><tt>&&</tt></td><td><tt>logical_action<and_action></tt></td></tr><tr><td><tt>||</tt></td><td><tt>logical_action<or_action></tt></td></tr><tr><td><tt>!</tt></td><td><tt>logical_action<not_action></tt></td></tr><tr><td><tt><</tt></td><td><tt>relational_action<less_action></tt></td></tr><tr><td><tt>></tt></td><td><tt>relational_action<greater_action></tt></td></tr><tr><td><tt><=</tt></td><td><tt>relational_action<lessorequal_action></tt></td></tr><tr><td><tt>>=</tt></td><td><tt>relational_action<greaterorequal_action></tt></td></tr><tr><td><tt>==</tt></td><td><tt>relational_action<equal_action></tt></td></tr><tr><td><tt>!=</tt></td><td><tt>relational_action<notequal_action></tt></td></tr><tr><td><tt>+=</tt></td><td><tt>arithmetic_assignment_action<plus_action></tt></td></tr><tr><td><tt>-=</tt></td><td><tt>arithmetic_assignment_action<minus_action></tt></td></tr><tr><td><tt>*=</tt></td><td><tt>arithmetic_assignment_action<multiply_action></tt></td></tr><tr><td><tt>/=</tt></td><td><tt>arithmetic_assignment_action<divide_action></tt></td></tr><tr><td><tt>%=</tt></td><td><tt>arithmetic_assignment_action<remainder_action></tt></td></tr><tr><td><tt>&=</tt></td><td><tt>bitwise_assignment_action<and_action></tt></td></tr><tr><td><tt>=|</tt></td><td><tt>bitwise_assignment_action<or_action></tt></td></tr><tr><td><tt>^=</tt></td><td><tt>bitwise_assignment_action<xor_action></tt></td></tr><tr><td><tt><<=</tt></td><td><tt>bitwise_assignment_action<leftshift_action></tt></td></tr><tr><td><tt>>>=</tt></td><td><tt>bitwise_assignment_action<rightshift_action></tt></td></tr><tr><td><tt>++</tt></td><td><tt>pre_increment_decrement_action<increment_action></tt></td></tr><tr><td><tt>--</tt></td><td><tt>pre_increment_decrement_action<decrement_action></tt></td></tr><tr><td><tt>++</tt></td><td><tt>post_increment_decrement_action<increment_action></tt></td></tr><tr><td><tt>--</tt></td><td><tt>post_increment_decrement_action<decrement_action></tt></td></tr><tr><td><tt>&</tt></td><td><tt>other_action<address_of_action></tt></td></tr><tr><td><tt>*</tt></td><td><tt>other_action<contents_of_action></tt></td></tr><tr><td><tt>,</tt></td><td><tt>other_action<comma_action></tt></td></tr></tbody></table></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ar01s05.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ar01s07.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">5. Lambda expressions in details </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 7. Practical considerations</td></tr></table></div></body></html>
|
||||
169
doc/ar01s07.html
Normal file
169
doc/ar01s07.html
Normal file
@@ -0,0 +1,169 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type"><title>7. Practical considerations</title><meta name="generator" content="DocBook XSL Stylesheets V1.48"><link rel="home" href="index.html" title="
|
||||
C++ BOOST
|
||||
|
||||
The Boost Lambda Library"><link rel="up" href="index.html" title="
|
||||
C++ BOOST
|
||||
|
||||
The Boost Lambda Library"><link rel="previous" href="ar01s06.html" title="6. Extending return type deduction system"><link rel="next" href="ar01s08.html" title="8. Relation to other Boost libraries"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">7. Practical considerations</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ar01s06.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ar01s08.html">Next</a></td></tr></table><hr></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="id2807566"></a>7. Practical considerations</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2807572"></a>7.1. Performance</h3></div></div><p>In theory, all overhead of using STL algorithms and lambda functors
|
||||
compared to hand written loops can be optimized away, just as the overhead
|
||||
from standard STL function objects and binders can.
|
||||
|
||||
Depending on the compiler, this can also be true in practice.
|
||||
We ran two tests with the GCC 3.0.4 compiler on 1.5 GHz Intel Pentium 4.
|
||||
The optimization flag -03 was used.
|
||||
</p><p>
|
||||
In the first test we compared lambda functors against explicitly written
|
||||
function objects.
|
||||
We used both of these styles to define unary functions which multiply the
|
||||
argument repeatedly by itself.
|
||||
We started with the identity function, going up to
|
||||
x<sup>5</sup>.
|
||||
The expressions were called inside a <tt>std::transform</tt> loop,
|
||||
reading the argument from one <tt>std::vector<int></tt>
|
||||
and placing the result into another.
|
||||
The length of the vectors was 100 elements.
|
||||
The running times are listed in
|
||||
<a href="ar01s07.html#table:increasing_arithmetic_test" title="Table 3. Test 1. CPU time of expressions with integer multiplication written as a lambda expression and as a traditional hand-coded function object class.
|
||||
The running times are expressed in arbitrary units.">Table 3</a>.
|
||||
|
||||
We can observe that there is no significant difference between the
|
||||
two approaches.
|
||||
</p><p>
|
||||
In the second test we again used <tt>std::transform</tt> to
|
||||
perform an operation to each element in a 100-element long vector.
|
||||
This time the element type of the vectors was <tt>double</tt>
|
||||
and we started with very simple arithmetic expressions and moved to
|
||||
more complex ones.
|
||||
The running times are listed in <a href="ar01s07.html#table:ll_vs_stl_test" title="Table 4. Test 2. CPU time of arithmetic expressions written as lambda
|
||||
expressions, as classic STL unnamed functions (using compose2, bind1st etc.) and as traditional hand-coded function object classes.
|
||||
Using BLL terminology,
|
||||
a and b are bound arguments in the expressions, and x is open.
|
||||
All variables were of types double.
|
||||
The running times are expressed in arbitrary units.">Table 4</a>.
|
||||
|
||||
Here, we also included classic STL style unnamed functions into tests.
|
||||
We do not show these expressions, as they get rather complex.
|
||||
For example, the
|
||||
last expression in <a href="ar01s07.html#table:ll_vs_stl_test" title="Table 4. Test 2. CPU time of arithmetic expressions written as lambda
|
||||
expressions, as classic STL unnamed functions (using compose2, bind1st etc.) and as traditional hand-coded function object classes.
|
||||
Using BLL terminology,
|
||||
a and b are bound arguments in the expressions, and x is open.
|
||||
All variables were of types double.
|
||||
The running times are expressed in arbitrary units.">Table 4</a> written with
|
||||
classic STL tools contains 7 calls to <tt>compose2</tt>,
|
||||
8 calls to <tt>bind1st</tt>
|
||||
and altogether 14 constructor invocations for creating
|
||||
<tt>multiplies</tt>, <tt>minus</tt>
|
||||
and <tt>plus</tt> objects.
|
||||
|
||||
In this test the BLL expressions are a little slower (roughly 10% on average,
|
||||
less than 14% in all cases)
|
||||
than the corresponding hand-written function objects.
|
||||
The performance hit is a bit greater with classic STL expressions,
|
||||
up to 27% for the simplest expressios.
|
||||
</p><p>
|
||||
The tests suggest that the BLL does not introduce a loss of performance
|
||||
compared to STL function objects.
|
||||
With a reasonable optimizing compiler, one should expect the performance characteristics be comparable to using classic STL.
|
||||
Moreover, with simple expressions the performance can be expected to be close
|
||||
to that of explicitly written function objects.
|
||||
|
||||
|
||||
|
||||
Note however, that evaluating a lambda functor consist of a sequence of calls to small functions that are declared inline.
|
||||
If the compiler fails to actually expand these functions inline,
|
||||
the performance can suffer.
|
||||
The running time can more than double if this happens.
|
||||
Although the above tests do not include such an expression, we have experienced
|
||||
this for some seemingly simple expressions.
|
||||
|
||||
|
||||
<div class="table"><p><a name="table:increasing_arithmetic_test"></a><b>Table 3. Test 1. CPU time of expressions with integer multiplication written as a lambda expression and as a traditional hand-coded function object class.
|
||||
The running times are expressed in arbitrary units.</b></p><table summary="Test 1. CPU time of expressions with integer multiplication written as a lambda expression and as a traditional hand-coded function object class.
|
||||
The running times are expressed in arbitrary units." border="1"><colgroup><col><col><col></colgroup><thead><tr><th>expression</th><th>lambda expression</th><th>hand-coded function object</th></tr></thead><tbody><tr><td>x</td><td>240</td><td>230</td></tr><tr><td>x*x</td><td>340</td><td>350</td></tr><tr><td>x*x*x</td><td>770</td><td>760</td></tr><tr><td>x*x*x*x</td><td>1180</td><td>1210</td></tr><tr><td>x*x*x*x*x</td><td>1950</td><td>1910</td></tr></tbody></table></div>
|
||||
</p><p>
|
||||
<div class="table"><p><a name="table:ll_vs_stl_test"></a><b>Table 4. Test 2. CPU time of arithmetic expressions written as lambda
|
||||
expressions, as classic STL unnamed functions (using <tt>compose2</tt>, <tt>bind1st</tt> etc.) and as traditional hand-coded function object classes.
|
||||
Using BLL terminology,
|
||||
<tt>a</tt> and <tt>b</tt> are bound arguments in the expressions, and <tt>x</tt> is open.
|
||||
All variables were of types <tt>double</tt>.
|
||||
The running times are expressed in arbitrary units.</b></p><table summary="Test 2. CPU time of arithmetic expressions written as lambda
|
||||
expressions, as classic STL unnamed functions (using compose2, bind1st etc.) and as traditional hand-coded function object classes.
|
||||
Using BLL terminology,
|
||||
a and b are bound arguments in the expressions, and x is open.
|
||||
All variables were of types double.
|
||||
The running times are expressed in arbitrary units." border="1"><colgroup><col><col><col><col></colgroup><thead><tr><th>expression</th><th>lambda expression</th><th>classic STL expression</th><th>hand-coded function object</th></tr></thead><tbody><tr><td>ax</td><td>330</td><td>370</td><td>290</td></tr><tr><td>-ax</td><td>350</td><td>370</td><td>310</td></tr><tr><td>ax-(a+x)</td><td>470</td><td>500</td><td>420</td></tr><tr><td>(ax-(a+x))(a+x)</td><td>620</td><td>670</td><td>600</td></tr><tr><td>((ax) - (a+x))(bx - (b+x))(ax - (b+x))(bx - (a+x))</td><td>1660</td><td>1660</td><td>1460</td></tr></tbody></table></div>
|
||||
</p><p>Some additional performance testing with an earlier version of the
|
||||
library is described
|
||||
[<a href="bi01.html#cit:jarvi:00" title="[Jär00]">Jär00</a>].
|
||||
</p></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2808065"></a>7.2. About compiling</h3></div></div><p>The BLL uses templates rather heavily, performing numerous recursive instantiations of the same templates.
|
||||
This has (at least) three implications:
|
||||
<div class="itemizedlist"><ul type="disc"><li><p>
|
||||
While it is possible to write incredibly complex lambda expressions, it probably isn't a good idea.
|
||||
Compiling such expressions may end up requiring a lot of memory
|
||||
at compile time, and being slow to compile.
|
||||
</p></li><li><p>
|
||||
The types of lambda functors that result from even the simplest lambda expressions are cryptic.
|
||||
Usually the programmer doesn't need to deal with the lambda functor the types at all, but in the case of an error in a lambda expression, the compiler usually outputs the types of the lambda functors involved.
|
||||
This can make the error messages very long and difficult to interpret, particularly if the compiler outputs the whole chain of template instantiations.
|
||||
</p></li><li><p>
|
||||
The C++ Standard suggests a template nesting level of 17 to help detect infinite recursion.
|
||||
Complex lambda templates can easily exceed this limit.
|
||||
Most compilers allow a greater number of nested templates, but commonly require the limit explicitly increased with a command line argument.
|
||||
</p></li></ul></div></p></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2808126"></a>7.3. Portability</h3></div></div><p>
|
||||
The BLL works with the following compilers, that is, the compilers are capable of compiling the test cases that are included with the BLL:
|
||||
|
||||
<div class="itemizedlist"><ul type="disc"><li>GCC 3.0.4
|
||||
</li><li>KCC 4.0f with EDG 2.43.1
|
||||
</li><li>GCC 2.96 (fails with one test case, the <tt>exception_test.cpp</tt> results in an internal compiler error.
|
||||
)
|
||||
|
||||
</li></ul></div>
|
||||
</p><div class="section"><div class="titlepage"><div><h4 class="title"><a name="id2808166"></a>7.3.1. Test coverage</h4></div></div><p>The following list describes the test files included and the features that each file covers:
|
||||
|
||||
<div class="itemizedlist"><ul type="disc"><li><p>
|
||||
<tt>bind_tests_simple.cpp</tt> : Bind expressions of different arities and types of target functions: function pointers, function objects and member functions.
|
||||
Function composition with bind expressions.</p></li><li><p><tt>bind_tests_simple_function_references.cpp</tt> :
|
||||
Repeats all tests from <tt>bind_tests_simple.cpp</tt> where the target function is a function pointer, but uses function references instead.
|
||||
</p></li><li><p><tt>bind_tests_advanced.cpp</tt> : Contains tests for nested bind expressions, <tt>unlambda</tt>, <tt>protect</tt>, <tt>const_parameters</tt> and <tt>break_const</tt>.
|
||||
Tests passing lambda functors as actual arguments to other lambda functors, currying, and using the <tt>sig</tt> template to specify the return type of a function object.
|
||||
</p></li><li><p>
|
||||
<tt>operator_tests_simple.cpp</tt> :
|
||||
Tests using all operators that are overloaded for lambda expressions, that is, unary and binary arithmetic,
|
||||
bitwise,
|
||||
comparison,
|
||||
logical,
|
||||
increment and decrement,
|
||||
compound,
|
||||
assignment,
|
||||
subscrict,
|
||||
address of,
|
||||
dereference, and comma operators.
|
||||
The streaming nature of shift operators is tested, as well as pointer arithmetic with plus and minus operators.
|
||||
</p></li><li><p><tt>member_pointer_test.cpp</tt> : The pointer to member operator is complex enough to warrant a separate test file.
|
||||
</p></li><li><p>
|
||||
<tt>control_structures.cpp</tt> :
|
||||
Tests for the looping and if constructs.
|
||||
</p></li><li><p>
|
||||
<tt>switch_construct.cpp</tt> :
|
||||
Includes tests for all supported arities of the switch statement, both with and without the default case.
|
||||
</p></li><li><p>
|
||||
<tt>exception_test.cpp</tt> :
|
||||
Includes tests for throwing exceptions and for try/catch constructs with varying number of catch blocks.
|
||||
</p></li><li><p>
|
||||
<tt>constructor_tests.cpp</tt> :
|
||||
Contains tests for <tt>constructor</tt>, <tt>destructor</tt>, <tt>new_ptr</tt>, <tt>delete_ptr</tt>, <tt>new_array</tt> and <tt>delete_array</tt>.
|
||||
</p></li><li><p>
|
||||
<tt>cast_test.cpp</tt> : Tests for the four cast expressions, as well as <tt>typeid</tt> and <tt>sizeof</tt>.
|
||||
</p></li><li><p>
|
||||
<tt>extending_return_type_traits.cpp</tt> : Tests extending the return type deduction system for user defined types.
|
||||
Contains several user defined operators and the corresponding specializations for the return type deduction templates.
|
||||
</p></li><li><p>
|
||||
<tt>is_instance_of_test.cpp</tt> : Includes tests for an internally used traits template, which can detect whether a given type is an instance of a certain template or not.
|
||||
</p></li><li><p>
|
||||
<tt>bll_and_function.cpp</tt> :
|
||||
Contains tests for using <tt>boost::function</tt> together with lambda functors.
|
||||
</p></li></ul></div>
|
||||
|
||||
</p></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ar01s06.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ar01s08.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">6. Extending return type deduction system </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 8. Relation to other Boost libraries</td></tr></table></div></body></html>
|
||||
124
doc/ar01s08.html
Normal file
124
doc/ar01s08.html
Normal file
@@ -0,0 +1,124 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type"><title>8. Relation to other Boost libraries</title><meta name="generator" content="DocBook XSL Stylesheets V1.48"><link rel="home" href="index.html" title="
|
||||
C++ BOOST
|
||||
|
||||
The Boost Lambda Library"><link rel="up" href="index.html" title="
|
||||
C++ BOOST
|
||||
|
||||
The Boost Lambda Library"><link rel="previous" href="ar01s07.html" title="7. Practical considerations"><link rel="next" href="ar01s09.html" title="9. Contributors"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">8. Relation to other Boost libraries</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ar01s07.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ar01s09.html">Next</a></td></tr></table><hr></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="id2808510"></a>8. Relation to other Boost libraries</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2808518"></a>8.1. Boost Function</h3></div></div><p>Sometimes it is convenient to store lambda functors in variables.
|
||||
However, the types of even the simplest lambda functors are long and unwieldy, and it is in general unfeasible to declare variables with lambda functor types.
|
||||
<span class="emphasis"><i>The Boost Function library</i></span> [<a href="bi01.html#cit:boost::function" title="[function]">function</a>] defines wrappers for arbitrary function objects, for example
|
||||
lambda functors; and these wrappers have types that are easy to type out.
|
||||
|
||||
For example:
|
||||
|
||||
<pre class="programlisting">
|
||||
boost::function<int(int, int)> f = _1 + _2;
|
||||
boost::function<int&(int&)> g = (_1 += 10);
|
||||
int i = 1, j = 2;
|
||||
f(i); // returns 3
|
||||
g(i); // sets i to = 11;
|
||||
</pre>
|
||||
|
||||
The return and parameter types of the wrapped function object must be written explicilty as the template argument to the wrapper template <tt>boost::function</tt>; even when lambda functors, which otherwise have generic parameters, are wrapped.
|
||||
Wrapping a function object with <tt>boost::function</tt> introduces a performance cost comparable to virtual function dispatch, though virtual functions are not actually used.
|
||||
|
||||
Note that storing lambda functors inside <tt>boost::function</tt>
|
||||
introduces a danger.
|
||||
Certain types of lambda functors may store references to the bound
|
||||
arguments, instead as taking copies of the arguments of the lambda expression.
|
||||
When temporary lambda functor objects are used
|
||||
in STL algorithm invocations this is always safe, as the lambda functor gets
|
||||
destructed immediately after the STL algortihm invocation is completed.
|
||||
|
||||
However, a lambda functor wrapped inside <tt>boost::function</tt>
|
||||
may continue to exist longer, creating the possibility of dangling references.
|
||||
For example:
|
||||
|
||||
<pre class="programlisting">
|
||||
int* sum = new int();
|
||||
*sum = 0;
|
||||
boost::function<int&(int)> counter = *sum += _1;
|
||||
counter(5); // ok, *sum = 5;
|
||||
delete sum;
|
||||
counter(3); // error, *sum does not exist anymore
|
||||
</pre>
|
||||
|
||||
</p></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2808622"></a>8.2. Boost Bind</h3></div></div><p>
|
||||
<span class="emphasis"><i>The Boost Bind</i></span> [<a href="bi01.html#cit:boost::bind" title="[bind]">bind</a>] library has partially overlapping functionality with the BLL.
|
||||
Basically, the Boost Bind library (BB in the sequel) implements the bind expression part of BLL.
|
||||
There are, however, some semantical differerences.
|
||||
</p><p>
|
||||
The BLL and BB evolved separately, and have different implementations.
|
||||
This means that the bind expressions from the BB cannot be used within
|
||||
bind expressions, or within other type of lambda expressions, of the BLL.
|
||||
The same holds for using BLL bind expressions in the BB.
|
||||
The libraries can coexist, however, as
|
||||
the names of the BB library are in <tt>boost</tt> namespace,
|
||||
whereas the BLL names are in <tt>boost::lambda</tt> namespace.
|
||||
</p><p>
|
||||
The BLL requires a compiler that is reasonably conformant to the
|
||||
C++ standard, whereas the BB library is more portable, and works with
|
||||
a larger set of compilers.
|
||||
</p><p>
|
||||
The following two sections describe what are the semantic differences
|
||||
between the bind expressions in BB and BLL.
|
||||
</p><div class="section"><div class="titlepage"><div><h4 class="title"><a name="id2808686"></a>8.2.1. First argument of bind expression</h4></div></div>
|
||||
|
||||
In BB the first argument of the bind expression, the target function,
|
||||
is treated differently from the other arguments,
|
||||
as no argument substitution takes place within that argument.
|
||||
In BLL the first argument is not a special case in this respect.
|
||||
|
||||
For example:
|
||||
|
||||
<pre class="programlisting">
|
||||
template<class F>
|
||||
int foo(const F& f) {
|
||||
int x;
|
||||
..
|
||||
bind(f, _1)(x);
|
||||
...
|
||||
}
|
||||
</pre><pre class="programlisting">
|
||||
int bar(int, int);
|
||||
nested(bind(bar, 1, _1));
|
||||
</pre>
|
||||
|
||||
The bind expression inside <tt>foo</tt> becomes:
|
||||
<pre class="programlisting">
|
||||
bind(bind(bar, 1, _1), _1)(x)
|
||||
</pre>
|
||||
|
||||
The BLL interpretes this as:
|
||||
<pre class="programlisting">
|
||||
bar(1, x)(x)
|
||||
</pre>
|
||||
whereas the BB library as
|
||||
<pre class="programlisting">
|
||||
bar(1, x)
|
||||
</pre>
|
||||
|
||||
To get this functionality in BLL, the bind expression inside the <tt>foo</tt> function can be written as:
|
||||
<pre class="programlisting">
|
||||
bind(unlambda(f), _1)(x);
|
||||
</pre>
|
||||
as explained in <a href="ar01s05.html#sect:unlambda" title="5.9.1.1. Unlambda">Section 5.9.1.1</a>.
|
||||
|
||||
</div><p>
|
||||
The BB library supports up to nine placeholders, while the BLL
|
||||
defines only three placeholders.
|
||||
The rationale for not providing more, is that the highest arity of the
|
||||
function objects accepted by any STL algorithm is two.
|
||||
The placeholder count is easy to increase in the BB library.
|
||||
In BLL it is possible, but more laborous.
|
||||
The BLL currently passes the actual arguments to the lambda functors
|
||||
internally just as they are and does not wrap them inside a tuple object.
|
||||
The reason for this is that some widely used compilers are not capable
|
||||
of optimizing the intermediate tuple objects away.
|
||||
The creation of the intermediate tuples would cause a significant
|
||||
performance hit, particularly for the simplest (and thus the most common)
|
||||
lambda functors.
|
||||
We are working on a hybrid approach, which will allow more placeholders
|
||||
but not compromise the performance of simple lambda functors.
|
||||
</p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ar01s07.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ar01s09.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">7. Practical considerations </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 9. Contributors</td></tr></table></div></body></html>
|
||||
16
doc/ar01s09.html
Normal file
16
doc/ar01s09.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type"><title>9. Contributors</title><meta name="generator" content="DocBook XSL Stylesheets V1.48"><link rel="home" href="index.html" title="
|
||||
C++ BOOST
|
||||
|
||||
The Boost Lambda Library"><link rel="up" href="index.html" title="
|
||||
C++ BOOST
|
||||
|
||||
The Boost Lambda Library"><link rel="previous" href="ar01s08.html" title="8. Relation to other Boost libraries"><link rel="next" href="apa.html" title="A. Rationale for some of the design decisions"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">9. Contributors</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ar01s08.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="apa.html">Next</a></td></tr></table><hr></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="id2808801"></a>9. Contributors</h2></div></div>
|
||||
|
||||
The main body of the library was written by Jaakko Järvi and Gary Powell.
|
||||
We've got outside help, suggestions and ideas from Jeremy Siek, Peter Higley, Peter Dimov, Valentin Bonnard, William Kempf.
|
||||
We would particularly like to mention Joel de Guzmann and his work with
|
||||
Phoenix which has influenced BLL significantly, making it considerably simpler
|
||||
to extend the library with new features.
|
||||
|
||||
</div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ar01s08.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="apa.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8. Relation to other Boost libraries </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> A. Rationale for some of the design decisions</td></tr></table></div></body></html>
|
||||
19
doc/bi01.html
Normal file
19
doc/bi01.html
Normal file
@@ -0,0 +1,19 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type"><title>Bibliography</title><meta name="generator" content="DocBook XSL Stylesheets V1.48"><link rel="home" href="index.html" title="
|
||||
C++ BOOST
|
||||
|
||||
The Boost Lambda Library"><link rel="up" href="index.html" title="
|
||||
C++ BOOST
|
||||
|
||||
The Boost Lambda Library"><link rel="previous" href="apa.html" title="A. Rationale for some of the design decisions"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Bibliography</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="apa.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> </td></tr></table><hr></div><div id="id2808975" class="bibliography"><div class="titlepage"><div><h2 class="title"><a name="id2808975"></a>Bibliography</h2></div></div><div class="biblioentry"><a name="cit:stepanov:94"></a><p>[STL94] <span class="authorgroup">A. A. Stepanov and M. Lee. </span><span class="title"><I>The Standard Template Library</I>. </span><span class="orgname">Hewlett-Packard Laboratories. </span><span class="pubdate">1994. </span><span class="bibliomisc">
|
||||
<a href="http://www.hpl.hp.com/techreports" target="_top">www.hpl.hp.com/techreports</a>
|
||||
. </span></p></div><div class="biblioentry"><a name="cit:sgi:02"></a><p>[SGI02] <span class="title"><I>The SGI Standard Template Library</I>. </span><span class="pubdate">2002. </span><span class="bibliomisc"><a href="http://www.sgi.com/tech/stl/" target="_top">www.sgi.com/tech/stl/</a>. </span></p></div><div class="biblioentry"><a name="cit:c++:98"></a><p>[C++98] <span class="title"><I>International Standard, Programming Languages – C++</I>. </span><span class="subtitle">ISO/IEC:14882. </span><span class="pubdate">1998. </span></p></div><div class="biblioentry"><a name="cit:jarvi:99"></a><p>[Jär99] <span class="articleinfo">
|
||||
<span class="author">Jaakko Järvi. </span>
|
||||
<span class="title"><I>C++ Function Object Binders Made Easy</I>. </span>
|
||||
. </span><span class="title"><I>Lecture Notes in Computer Science</I>. </span><span class="volumenum">1977. </span><span class="publishername">Springer. </span><span class="pubdate">2000. </span></p></div><div class="biblioentry"><a name="cit:jarvi:00"></a><p>[Jär00] <span class="author">Jaakko Järvi. </span><span class="author">Gary Powell. </span><span class="title"><I>The Lambda Library : Lambda Abstraction in C++</I>. </span><span class="orgname">Turku Centre for Computer Science. </span><span class="bibliomisc">Technical Report . </span><span class="issuenum">378. </span><span class="pubdate">2000. </span><span class="bibliomisc"><a href="http://www.tucs.fi/Publications/techreports/TR378.php" target="_top">www.tucs.fi/publications</a>. </span></p></div><div class="biblioentry"><a name="cit:jarvi:01"></a><p>[Jär01] <span class="author">Jaakko Järvi. </span><span class="author">Gary Powell. </span><span class="title"><I>The Lambda Library : Lambda Abstraction in C++</I>. </span><span class="confgroup"><span class="conftitle">Second Workshop on C++ Template Programming. </span><span class="address">Tampa Bay, OOPSLA'01. </span>. </span><span class="pubdate">2001. </span><span class="bibliomisc"><a href="http://www.oonumerics.org/tmpw01/" target="_top">www.oonumerics.org/tmpw01/</a>. </span></p></div><div class="biblioentry"><a name="cit:boost::tuple"></a><p>[tuple] <span class="title"><I>The Boost Tuple Library</I>. </span><span class="bibliomisc"><a href="http://www.boost.org/libs/tuple/doc/tuple_users_guide.html" target="_top">www.boost.org/libs/tuple/doc/tuple_users_guide.html</a>
|
||||
. </span><span class="pubdate">2002. </span></p></div><div class="biblioentry"><a name="cit:boost::type_traits"></a><p>[type_traits] <span class="title"><I>The Boost type_traits</I>. </span><span class="bibliomisc"><a href="http://www.boost.org/libs/type_traits/index.htm" target="_top">www.boost.org/libs/type_traits/</a>
|
||||
. </span><span class="pubdate">2002. </span></p></div><div class="biblioentry"><a name="cit:boost::ref"></a><p>[ref] <span class="title"><I>Boost ref</I>. </span><span class="bibliomisc"><a href="http://www.boost.org/libs/bind/ref.html" target="_top">www.boost.org/libs/bind/ref.html</a>
|
||||
. </span><span class="pubdate">2002. </span></p></div><div class="biblioentry"><a name="cit:boost::bind"></a><p>[bind] <span class="title"><I>Boost Bind Library</I>. </span><span class="bibliomisc"><a href="http://www.boost.org/libs/bind/bind.html" target="_top">www.boost.org/libs/bind/bind.html</a>
|
||||
. </span><span class="pubdate">2002. </span></p></div><div class="biblioentry"><a name="cit:boost::function"></a><p>[function] <span class="title"><I>Boost Function Library</I>. </span><span class="bibliomisc"><a href="http://www.boost.org/libs/function/" target="_top">www.boost.org/libs/function/</a>
|
||||
. </span><span class="pubdate">2002. </span></p></div><div class="biblioentry"><a name="cit:fc++"></a><p>[fc++] <span class="title"><I>The FC++ library: Functional Programming in C++</I>. </span><span class="author">Yannis Smaragdakis. </span><span class="author">Brian McNamara. </span><span class="bibliomisc"><a href="http://www.cc.gatech.edu/~yannis/fc++/" target="_top">www.cc.gatech.edu/~yannis/fc++/</a>
|
||||
. </span><span class="pubdate">2002. </span></p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="apa.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td><td width="40%" align="right"> </td></tr><tr><td width="40%" align="left" valign="top">A. Rationale for some of the design decisions </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div></body></html>
|
||||
7
doc/detail/README
Normal file
7
doc/detail/README
Normal file
@@ -0,0 +1,7 @@
|
||||
- lambda_doc.xml is a DocBook xml file from which the lambda docs are
|
||||
generated
|
||||
- lambda_doc_chunks.xsl loads the stylesheets that generate a separate
|
||||
html-file for each section
|
||||
- lambda_doc.xsl loads stylesheets that generate one big html-file
|
||||
(you need to edit the paths in these files to make them work)
|
||||
|
||||
3422
doc/detail/lambda_doc.xml
Executable file
3422
doc/detail/lambda_doc.xml
Executable file
File diff suppressed because it is too large
Load Diff
19
doc/detail/lambda_doc.xsl
Normal file
19
doc/detail/lambda_doc.xsl
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version='1.0'?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
version='1.0'
|
||||
xmlns="http://www.w3.org/TR/xhtml1/transitional"
|
||||
exclude-result-prefixes="#default">
|
||||
|
||||
<xsl:import href="/u/jajarvi/dtd/docbook-xsl/html/docbook.xsl"/>
|
||||
|
||||
|
||||
<!-- Add other variable definitions here -->
|
||||
|
||||
<xsl:variable name="shade.verbatim">0</xsl:variable>
|
||||
|
||||
<xsl:variable name="section.autolabel">1</xsl:variable>
|
||||
|
||||
<xsl:variable name="bibliography.collection">lambda_bib.xml</xsl:variable>
|
||||
|
||||
|
||||
</xsl:stylesheet>
|
||||
19
doc/detail/lambda_doc_chunks.xsl
Normal file
19
doc/detail/lambda_doc_chunks.xsl
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version='1.0'?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
version='1.0'
|
||||
xmlns="http://www.w3.org/TR/xhtml1/transitional"
|
||||
exclude-result-prefixes="#default">
|
||||
|
||||
<xsl:import href="/u/jajarvi/dtd/docbook-xsl/html/chunk.xsl"/>
|
||||
|
||||
|
||||
<!-- Add other variable definitions here -->
|
||||
|
||||
<xsl:variable name="shade.verbatim">0</xsl:variable>
|
||||
|
||||
<xsl:variable name="section.autolabel">1</xsl:variable>
|
||||
|
||||
<xsl:variable name="bibliography.collection">lambda_bib.xml</xsl:variable>
|
||||
|
||||
|
||||
</xsl:stylesheet>
|
||||
39
doc/index.html
Normal file
39
doc/index.html
Normal file
@@ -0,0 +1,39 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type"><title>
|
||||
C++ BOOST
|
||||
|
||||
The Boost Lambda Library</title><meta name="generator" content="DocBook XSL Stylesheets V1.48"><link rel="home" href="index.html" title="
|
||||
C++ BOOST
|
||||
|
||||
The Boost Lambda Library"><link rel="next" href="ar01s02.html" title="2. Getting Started"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">
|
||||
C++ BOOST
|
||||
|
||||
The Boost Lambda Library</th></tr><tr><td width="20%" align="left"> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ar01s02.html">Next</a></td></tr></table><hr></div><div class="article"><div class="titlepage"><div><h1 class="title"><a name="id2733457"></a>
|
||||
<span class="inlinemediaobject"><img src="../../../c++boost.gif" alt="C++ BOOST"></span>
|
||||
|
||||
The Boost Lambda Library</h1></div><div><p class="copyright">Copyright © 1999-2002 Jaakko Järvi, Gary Powell</p></div><div><div class="legalnotice"><p>
|
||||
The Boost Lambda Library is free software; Permission to copy,
|
||||
use, modify and distribute this software and its documentation is granted, provided this copyright
|
||||
notice appears in all copies.
|
||||
</p></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt>1. <a href="index.html#introduction">In a nutshell</a></dt><dt>2. <a href="ar01s02.html">Getting Started</a></dt><dd><dl><dt>2.1. <a href="ar01s02.html#id2790118">Installing the library</a></dt><dt>2.2. <a href="ar01s02.html#id2741945">Conventions used in this document</a></dt></dl></dd><dt>3. <a href="ar01s03.html">Introduction</a></dt><dd><dl><dt>3.1. <a href="ar01s03.html#id2741999">Motivation</a></dt><dt>3.2. <a href="ar01s03.html#id2742792">Introduction to lambda expressions</a></dt></dl></dd><dt>4. <a href="ar01s04.html">Using the library</a></dt><dd><dl><dt>4.1. <a href="ar01s04.html#sect:introductory_examples">Introductory Examples</a></dt><dt>4.2. <a href="ar01s04.html#sect:parameter_and_return_types">Parameter and return types of lambda functors</a></dt><dt>4.3. <a href="ar01s04.html#sect:actual_arguments_to_lambda_functors">About actual arguments to lambda functors</a></dt><dt>4.4. <a href="ar01s04.html#sect:storing_bound_arguments">Storing bound arguments in lambda functions</a></dt></dl></dd><dt>5. <a href="ar01s05.html">Lambda expressions in details</a></dt><dd><dl><dt>5.1. <a href="ar01s05.html#sect:placeholders">Placeholders</a></dt><dt>5.2. <a href="ar01s05.html#sect:operator_expressions">Operator expressions</a></dt><dt>5.3. <a href="ar01s05.html#sect:bind_expressions">Bind expressions</a></dt><dt>5.4. <a href="ar01s05.html#sect:overriding_deduced_return_type">Overriding the deduced return type</a></dt><dt>5.5. <a href="ar01s05.html#sect:delaying_constants_and_variables">Delaying constants and variables</a></dt><dt>5.6. <a href="ar01s05.html#sect:lambda_expressions_for_control_structures">Lambda expressions for control structures</a></dt><dt>5.7. <a href="ar01s05.html#sect:exceptions">Exceptions</a></dt><dt>5.8. <a href="ar01s05.html#sect:construction_and_destruction">Construction and destruction</a></dt><dt>5.9. <a href="ar01s05.html#id2805484">Special lambda expressions</a></dt><dt>5.10. <a href="ar01s05.html#id2806057">Casts, sizeof and typeid</a></dt><dt>5.11. <a href="ar01s05.html#sect:nested_stl_algorithms">Nesting STL algorithm invocations</a></dt></dl></dd><dt>6. <a href="ar01s06.html">Extending return type deduction system</a></dt><dt>7. <a href="ar01s07.html">Practical considerations</a></dt><dd><dl><dt>7.1. <a href="ar01s07.html#id2807572">Performance</a></dt><dt>7.2. <a href="ar01s07.html#id2808065">About compiling</a></dt><dt>7.3. <a href="ar01s07.html#id2808126">Portability</a></dt></dl></dd><dt>8. <a href="ar01s08.html">Relation to other Boost libraries</a></dt><dd><dl><dt>8.1. <a href="ar01s08.html#id2808518">Boost Function</a></dt><dt>8.2. <a href="ar01s08.html#id2808622">Boost Bind</a></dt></dl></dd><dt>9. <a href="ar01s09.html">Contributors</a></dt><dt>A. <a href="apa.html">Rationale for some of the design decisions</a></dt><dd><dl><dt>1. <a href="apa.html#sect:why_weak_arity">
|
||||
Lambda functor arity
|
||||
</a></dt></dl></dd><dt><a href="bi01.html">Bibliography</a></dt></dl></div><a href="lambda_docs_as_one_file.html" target="_top">Documentation as a one big HTML-file</a><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="introduction"></a>1. In a nutshell</h2></div></div><p>
|
||||
|
||||
The Boost Lambda Library (BLL in the sequel) is a C++ template
|
||||
library, which implements form of <span class="emphasis"><i>lambda abstractions</i></span> for C++.
|
||||
The term originates from functional programming and lambda calculus, where a lambda abstraction defines an unnamed function.
|
||||
The primary motivation for the BLL is to provide flexible and
|
||||
convenient means to define unnamed function objects for STL algorithms.
|
||||
In explaining what the library is about, a line of code says more than a thousand words; the
|
||||
following line outputs the elements of some STL container
|
||||
<tt>a</tt> separated by spaces:
|
||||
|
||||
<pre class="programlisting">for_each(a.begin(), a.end(), std::cout << _1 << ' ');</pre>
|
||||
|
||||
The expression <tt>std::cout << _1 << ' '</tt> defines a unary function object.
|
||||
The variable <tt>_1</tt> is the parameter of this function, a <span class="emphasis"><i>placeholder</i></span> for the actual argument.
|
||||
Within each iteration of <tt>for_each</tt>, the function is
|
||||
called with an element of <tt>a</tt> as the actual argument.
|
||||
This actual argument is substituted for the placeholder, and the ‘body’ of the function is evaluated.
|
||||
</p><p>The essence of BLL is letting you define small unnamed function objects, such as the one above, directly on the call site of an STL algorithm.
|
||||
</p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="ar01s02.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"> </td><td width="40%" align="right" valign="top"> 2. Getting Started</td></tr></table></div></body></html>
|
||||
2174
doc/lambda_docs_as_one_file.html
Normal file
2174
doc/lambda_docs_as_one_file.html
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -3,9 +3,14 @@
|
||||
// Copyright (C) 1999-2001 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Gary Powell (gwpowell@hotmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see http://www.boost.org
|
||||
|
||||
|
||||
@@ -3,9 +3,14 @@
|
||||
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see http://www.boost.org
|
||||
|
||||
|
||||
@@ -4,9 +4,24 @@
|
||||
Phoenix V0.9
|
||||
Copyright (c) 2001-2002 Joel de Guzman
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the copyright holder be held liable for
|
||||
any damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute
|
||||
it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
URL: http://spirit.sourceforge.net/
|
||||
|
||||
|
||||
@@ -3,9 +3,14 @@
|
||||
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see http://www.boost.org
|
||||
//
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
// -- control_structures.hpp -- Boost Lambda Library --------------------------
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
|
||||
@@ -3,9 +3,14 @@
|
||||
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
//
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
|
||||
// For more information, see www.boost.org
|
||||
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
//
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see http://www.boost.org
|
||||
|
||||
@@ -36,7 +41,6 @@ template<class T> struct constify_non_funcs {
|
||||
}
|
||||
#endif
|
||||
// 1-argument bind functions --------------------------
|
||||
#ifndef BOOST_REF_TO_FUNC_CONFLICTS_WITH_REF_TO_T
|
||||
template <class Result>
|
||||
inline const
|
||||
lambda_functor<
|
||||
@@ -46,7 +50,7 @@ lambda_functor<
|
||||
>
|
||||
>
|
||||
|
||||
bind(Result(& a1)()) {
|
||||
bind(Result(&a1)()) {
|
||||
return
|
||||
lambda_functor_base<
|
||||
action<1, function_action<1, Result> >,
|
||||
@@ -56,7 +60,7 @@ bind(Result(& a1)()) {
|
||||
(a1)
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef BOOST_LAMBDA_INCORRECT_BIND_OVERLOADING
|
||||
template <class Arg1>
|
||||
@@ -174,10 +178,9 @@ bind(Result(* const & a1)()) {
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// 2-argument bind functions --------------------------
|
||||
#ifndef BOOST_REF_TO_FUNC_CONFLICTS_WITH_REF_TO_T
|
||||
template <class Result, class Par1, class Arg2>
|
||||
inline const
|
||||
lambda_functor<
|
||||
@@ -197,9 +200,9 @@ bind(Result(&a1)(Par1), const Arg2& a2) {
|
||||
(a1, a2)
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_LAMBDA_INCORRECT_BIND_OVERLOADING
|
||||
|
||||
#ifndef BOOST_LAMBDA_INCORRECT_BIND_OVERLOADING
|
||||
template <class Arg1, class Arg2>
|
||||
inline const
|
||||
lambda_functor<
|
||||
@@ -318,7 +321,6 @@ bind(Result(* const & a1)(Par1), const Arg2& a2) {
|
||||
#endif
|
||||
|
||||
// 3-argument bind functions --------------------------
|
||||
#ifndef BOOST_REF_TO_FUNC_CONFLICTS_WITH_REF_TO_T
|
||||
template <class Result, class Par1, class Par2, class Arg2, class Arg3>
|
||||
inline const
|
||||
lambda_functor<
|
||||
@@ -344,7 +346,7 @@ bind(Result(&a1)(Par1, Par2), const Arg2& a2, const Arg3& a3) {
|
||||
(a1, a2, a3)
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef BOOST_LAMBDA_INCORRECT_BIND_OVERLOADING
|
||||
template <class Arg1, class Arg2, class Arg3>
|
||||
@@ -487,7 +489,6 @@ bind(Result(* const & a1)(Par1, Par2), const Arg2& a2, const Arg3& a3) {
|
||||
#endif
|
||||
|
||||
// 4-argument bind functions --------------------------
|
||||
#ifndef BOOST_REF_TO_FUNC_CONFLICTS_WITH_REF_TO_T
|
||||
template <class Result, class Par1, class Par2, class Par3, class Arg2,
|
||||
class Arg3, class Arg4>
|
||||
inline const
|
||||
@@ -515,7 +516,7 @@ bind(Result(&a1)(Par1, Par2, Par3), const Arg2& a2, const Arg3& a3,
|
||||
(a1, a2, a3, a4)
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef BOOST_LAMBDA_INCORRECT_BIND_OVERLOADING
|
||||
template <class Arg1, class Arg2, class Arg3, class Arg4>
|
||||
@@ -662,7 +663,6 @@ bind(Result(* const & a1)(Par1, Par2, Par3), const Arg2& a2,
|
||||
#endif
|
||||
|
||||
// 5-argument bind functions --------------------------
|
||||
#ifndef BOOST_REF_TO_FUNC_CONFLICTS_WITH_REF_TO_T
|
||||
template <class Result, class Par1, class Par2, class Par3, class Par4,
|
||||
class Arg2, class Arg3, class Arg4, class Arg5>
|
||||
inline const
|
||||
@@ -693,7 +693,7 @@ bind(Result(&a1)(Par1, Par2, Par3, Par4), const Arg2& a2, const Arg3& a3,
|
||||
(a1, a2, a3, a4, a5)
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef BOOST_LAMBDA_INCORRECT_BIND_OVERLOADING
|
||||
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
|
||||
@@ -849,7 +849,6 @@ bind(Result(* const & a1)(Par1, Par2, Par3, Par4), const Arg2& a2,
|
||||
#endif
|
||||
|
||||
// 6-argument bind functions --------------------------
|
||||
#ifndef BOOST_REF_TO_FUNC_CONFLICTS_WITH_REF_TO_T
|
||||
template <class Result, class Par1, class Par2, class Par3, class Par4,
|
||||
class Par5, class Arg2, class Arg3, class Arg4, class Arg5,
|
||||
class Arg6>
|
||||
@@ -881,7 +880,7 @@ bind(Result(&a1)(Par1, Par2, Par3, Par4, Par5), const Arg2& a2,
|
||||
(a1, a2, a3, a4, a5, a6)
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef BOOST_LAMBDA_INCORRECT_BIND_OVERLOADING
|
||||
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
|
||||
@@ -1040,7 +1039,6 @@ bind(Result(* const & a1)(Par1, Par2, Par3, Par4, Par5), const Arg2& a2,
|
||||
#endif
|
||||
|
||||
// 7-argument bind functions --------------------------
|
||||
#ifndef BOOST_REF_TO_FUNC_CONFLICTS_WITH_REF_TO_T
|
||||
template <class Result, class Par1, class Par2, class Par3, class Par4,
|
||||
class Par5, class Par6, class Arg2, class Arg3, class Arg4,
|
||||
class Arg5, class Arg6, class Arg7>
|
||||
@@ -1073,7 +1071,7 @@ bind(Result(&a1)(Par1, Par2, Par3, Par4, Par5, Par6), const Arg2& a2,
|
||||
(a1, a2, a3, a4, a5, a6, a7)
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef BOOST_LAMBDA_INCORRECT_BIND_OVERLOADING
|
||||
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
|
||||
@@ -1239,7 +1237,6 @@ bind(Result(* const & a1)(Par1, Par2, Par3, Par4, Par5, Par6),
|
||||
#endif
|
||||
|
||||
// 8-argument bind functions --------------------------
|
||||
#ifndef BOOST_REF_TO_FUNC_CONFLICTS_WITH_REF_TO_T
|
||||
template <class Result, class Par1, class Par2, class Par3, class Par4,
|
||||
class Par5, class Par6, class Par7, class Arg2, class Arg3,
|
||||
class Arg4, class Arg5, class Arg6, class Arg7, class Arg8>
|
||||
@@ -1272,7 +1269,7 @@ bind(Result(&a1)(Par1, Par2, Par3, Par4, Par5, Par6, Par7), const Arg2& a2,
|
||||
(a1, a2, a3, a4, a5, a6, a7, a8)
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef BOOST_LAMBDA_INCORRECT_BIND_OVERLOADING
|
||||
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
|
||||
@@ -1438,7 +1435,6 @@ bind(Result(* const & a1)(Par1, Par2, Par3, Par4, Par5, Par6, Par7),
|
||||
#endif
|
||||
|
||||
// 9-argument bind functions --------------------------
|
||||
#ifndef BOOST_REF_TO_FUNC_CONFLICTS_WITH_REF_TO_T
|
||||
template <class Result, class Par1, class Par2, class Par3, class Par4,
|
||||
class Par5, class Par6, class Par7, class Par8, class Arg2,
|
||||
class Arg3, class Arg4, class Arg5, class Arg6, class Arg7,
|
||||
@@ -1475,7 +1471,7 @@ bind(Result(&a1)(Par1, Par2, Par3, Par4, Par5, Par6, Par7, Par8),
|
||||
(a1, a2, a3, a4, a5, a6, a7, a8, a9)
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef BOOST_LAMBDA_INCORRECT_BIND_OVERLOADING
|
||||
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
|
||||
@@ -1653,7 +1649,6 @@ bind(Result(* const & a1)(Par1, Par2, Par3, Par4, Par5, Par6, Par7, Par8),
|
||||
#endif
|
||||
|
||||
// 10-argument bind functions --------------------------
|
||||
#ifndef BOOST_REF_TO_FUNC_CONFLICTS_WITH_REF_TO_T
|
||||
template <class Result, class Par1, class Par2, class Par3, class Par4,
|
||||
class Par5, class Par6, class Par7, class Par8, class Par9,
|
||||
class Arg2, class Arg3, class Arg4, class Arg5, class Arg6,
|
||||
@@ -1691,7 +1686,7 @@ bind(Result(&a1)(Par1, Par2, Par3, Par4, Par5, Par6, Par7, Par8, Par9),
|
||||
(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef BOOST_LAMBDA_INCORRECT_BIND_OVERLOADING
|
||||
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
|
||||
|
||||
@@ -3,9 +3,14 @@
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
|
||||
@@ -3,9 +3,14 @@
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
|
||||
// Copyright (C) 2001 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
@@ -18,18 +23,14 @@
|
||||
|
||||
|
||||
# if defined __GNUC__
|
||||
# if (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
|
||||
# define BOOST_REF_TO_FUNC_CONFLICTS_WITH_REF_TO_T
|
||||
# define BOOST_LAMBDA_INCORRECT_BIND_OVERLOADING
|
||||
# endif
|
||||
# if (__GNUC__ == 2 && __GNUC_MINOR__ <= 97)
|
||||
# define BOOST_NO_TEMPLATED_STREAMS
|
||||
# define BOOST_LAMBDA_INCORRECT_BIND_OVERLOADING
|
||||
# endif
|
||||
#define BOOST_NO_TEMPLATED_STREAMS
|
||||
#define BOOST_LAMBDA_INCORRECT_BIND_OVERLOADING
|
||||
#endif
|
||||
# if (__GNUC__ == 2 && __GNUC_MINOR__ <= 95)
|
||||
# define BOOST_LAMBDA_FAILS_IN_TEMPLATE_KEYWORD_AFTER_SCOPE_OPER
|
||||
# endif
|
||||
# endif // __GNUC__
|
||||
#define BOOST_LAMBDA_FAILS_IN_TEMPLATE_KEYWORD_AFTER_SCOPE_OPER
|
||||
#endif
|
||||
#endif // __GNUC__
|
||||
|
||||
|
||||
#if defined __KCC
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
//
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
@@ -27,7 +32,7 @@ public:
|
||||
|
||||
typedef T element_t;
|
||||
|
||||
// take all parameters as const references. Note that non-const references
|
||||
// take all parameters as const rererences. Note that non-const references
|
||||
// stay as they are.
|
||||
typedef typename boost::add_reference<
|
||||
typename boost::add_const<T>::type
|
||||
@@ -310,14 +315,14 @@ public:
|
||||
|
||||
|
||||
template<class RET, CALL_TEMPLATE_ARGS> RET call(CALL_FORMAL_ARGS) const {
|
||||
return CALL_USE_ARGS;
|
||||
CALL_USE_ARGS;
|
||||
}
|
||||
|
||||
template<class SigArgs> struct sig { typedef void type; };
|
||||
};
|
||||
|
||||
|
||||
// These specializations provide a shorter notation to define actions.
|
||||
// These specializatoins provide a shorter notation to define actions.
|
||||
// These lambda_functor_base instances take care of the recursive evaluation
|
||||
// of the arguments and pass the evaluated arguments to the apply function
|
||||
// of an action class. To make action X work with these classes, one must
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see http://www.boost.org
|
||||
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
@@ -65,7 +70,7 @@ void do_nothing(A1&, A2&, A3&, A4&) {}
|
||||
} // lambda
|
||||
} // boost
|
||||
|
||||
// prevent the warnings from unused arguments
|
||||
// prevent the warnings from unused argumetns
|
||||
#define CALL_USE_ARGS \
|
||||
::boost::lambda::detail::do_nothing(a, b, c, env)
|
||||
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
//
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@@ -3,9 +3,14 @@
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000 Gary Powell (gary.powell@sierra.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as of its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
|
||||
// For more information, see http://lambda.cs.utu.fi
|
||||
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
//
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
@@ -14,8 +19,6 @@
|
||||
#include "boost/lambda/detail/is_instance_of.hpp"
|
||||
#include "boost/type_traits/same_traits.hpp"
|
||||
|
||||
#include "boost/indirect_reference.hpp"
|
||||
|
||||
#include <cstddef> // needed for the ptrdiff_t
|
||||
#include <iosfwd> // for istream and ostream
|
||||
|
||||
@@ -218,7 +221,7 @@ namespace detail {
|
||||
|
||||
// A is a nonreference type
|
||||
template <class A> struct contentsof_type {
|
||||
typedef typename boost::indirect_reference<A>::type type;
|
||||
typedef typename std::iterator_traits<A>::reference type;
|
||||
};
|
||||
|
||||
// this is since the nullary () in lambda_functor is always instantiated
|
||||
@@ -489,6 +492,7 @@ struct promotion_of_unsigned_int
|
||||
{
|
||||
typedef
|
||||
detail::IF<sizeof(long) <= sizeof(unsigned int),
|
||||
// I had the logic reversed but ">" messes up the parsing.
|
||||
unsigned long,
|
||||
long>::RET type;
|
||||
};
|
||||
@@ -858,35 +862,14 @@ struct return_type_2<other_action<subscript_action>, A, B> {
|
||||
} // namespace boost
|
||||
|
||||
|
||||
// Forward declarations are incompatible with the libstdc++ debug mode.
|
||||
#if BOOST_WORKAROUND(__GNUC__, >= 3) && _GLIBCXX_DEBUG
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <deque>
|
||||
#else
|
||||
|
||||
// The GCC 2.95.x uses a non-conformant deque
|
||||
#if BOOST_WORKAROUND(__GNUC__, == 2) && __GNUC_MINOR__ <= 96
|
||||
#include <deque>
|
||||
#else
|
||||
|
||||
namespace std {
|
||||
template <class T, class Allocator> class deque;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace std {
|
||||
template <class Char, class Traits, class Allocator> class basic_string;
|
||||
template <class T, class Allocator> class vector;
|
||||
template <class Key, class T, class Cmp, class Allocator> class map;
|
||||
template <class Key, class T, class Cmp, class Allocator> class multimap;
|
||||
template <class T, class Allocator> class vector;
|
||||
template <class T, class Allocator> class deque;
|
||||
template <class Char, class Traits, class Allocator> class basic_string;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace lambda {
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
@@ -22,31 +27,22 @@ namespace lambda {
|
||||
#error "Multiple defines of BOOST_LAMBDA_BE1"
|
||||
#endif
|
||||
|
||||
// For all BOOSTA_LAMBDA_BE* macros:
|
||||
|
||||
// CONSTA must be either 'A' or 'const A'
|
||||
// CONSTB must be either 'B' or 'const B'
|
||||
|
||||
// It is stupid to have the names A and B as macro arguments, but it avoids
|
||||
// the need to pass in emtpy macro arguments, which gives warnings on some
|
||||
// compilers
|
||||
|
||||
#define BOOST_LAMBDA_BE1(OPER_NAME, ACTION, CONSTA, CONSTB, CONVERSION) \
|
||||
template<class Arg, class B> \
|
||||
inline const \
|
||||
lambda_functor< \
|
||||
lambda_functor_base< \
|
||||
ACTION, \
|
||||
tuple<lambda_functor<Arg>, typename CONVERSION <CONSTB>::type> \
|
||||
tuple<lambda_functor<Arg>, typename CONVERSION <CONSTB B>::type> \
|
||||
> \
|
||||
> \
|
||||
OPER_NAME (const lambda_functor<Arg>& a, CONSTB& b) { \
|
||||
OPER_NAME (const lambda_functor<Arg>& a, CONSTB B& b) { \
|
||||
return \
|
||||
lambda_functor_base< \
|
||||
ACTION, \
|
||||
tuple<lambda_functor<Arg>, typename CONVERSION <CONSTB>::type> \
|
||||
tuple<lambda_functor<Arg>, typename CONVERSION <CONSTB B>::type> \
|
||||
> \
|
||||
(tuple<lambda_functor<Arg>, typename CONVERSION <CONSTB>::type>(a, b)); \
|
||||
(tuple<lambda_functor<Arg>, typename CONVERSION <CONSTB B>::type>(a, b)); \
|
||||
}
|
||||
|
||||
|
||||
@@ -60,16 +56,16 @@ inline const \
|
||||
lambda_functor< \
|
||||
lambda_functor_base< \
|
||||
ACTION, \
|
||||
tuple<typename CONVERSION <CONSTA>::type, lambda_functor<Arg> > \
|
||||
tuple<typename CONVERSION <CONSTA A>::type, lambda_functor<Arg> > \
|
||||
> \
|
||||
> \
|
||||
OPER_NAME (CONSTA& a, const lambda_functor<Arg>& b) { \
|
||||
OPER_NAME (CONSTA A& a, const lambda_functor<Arg>& b) { \
|
||||
return \
|
||||
lambda_functor_base< \
|
||||
ACTION, \
|
||||
tuple<typename CONVERSION <CONSTA>::type, lambda_functor<Arg> > \
|
||||
tuple<typename CONVERSION <CONSTA A>::type, lambda_functor<Arg> > \
|
||||
> \
|
||||
(tuple<typename CONVERSION <CONSTA>::type, lambda_functor<Arg> >(a, b)); \
|
||||
(tuple<typename CONVERSION <CONSTA A>::type, lambda_functor<Arg> >(a, b)); \
|
||||
}
|
||||
|
||||
|
||||
@@ -104,37 +100,36 @@ BOOST_LAMBDA_BE1(OPER_NAME, ACTION, CONSTA, CONSTB, CONST_CONVERSION) \
|
||||
BOOST_LAMBDA_BE2(OPER_NAME, ACTION, CONSTA, CONSTB, CONST_CONVERSION) \
|
||||
BOOST_LAMBDA_BE3(OPER_NAME, ACTION, CONSTA, CONSTB, CONST_CONVERSION)
|
||||
|
||||
#define BOOST_LAMBDA_EMPTY()
|
||||
|
||||
BOOST_LAMBDA_BE(operator+, arithmetic_action<plus_action>, const A, const B, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator-, arithmetic_action<minus_action>, const A, const B, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator*, arithmetic_action<multiply_action>, const A, const B, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator/, arithmetic_action<divide_action>, const A, const B, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator%, arithmetic_action<remainder_action>, const A, const B, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator<<, bitwise_action<leftshift_action>, const A, const B, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator>>, bitwise_action<rightshift_action>, const A, const B, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator&, bitwise_action<and_action>, const A, const B, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator|, bitwise_action<or_action>, const A, const B, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator^, bitwise_action<xor_action>, const A, const B, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator&&, logical_action<and_action>, const A, const B, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator||, logical_action<or_action>, const A, const B, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator<, relational_action<less_action>, const A, const B, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator>, relational_action<greater_action>, const A, const B, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator<=, relational_action<lessorequal_action>, const A, const B, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator>=, relational_action<greaterorequal_action>, const A, const B, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator==, relational_action<equal_action>, const A, const B, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator!=, relational_action<notequal_action>, const A, const B, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator+, arithmetic_action<plus_action>, const, const, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator-, arithmetic_action<minus_action>, const, const, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator*, arithmetic_action<multiply_action>, const, const, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator/, arithmetic_action<divide_action>, const, const, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator%, arithmetic_action<remainder_action>, const, const, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator<<, bitwise_action<leftshift_action>, const, const, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator>>, bitwise_action<rightshift_action>, const, const, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator&, bitwise_action<and_action>, const, const, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator|, bitwise_action<or_action>, const, const, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator^, bitwise_action<xor_action>, const, const, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator&&, logical_action<and_action>, const, const, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator||, logical_action<or_action>, const, const, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator<, relational_action<less_action>, const, const, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator>, relational_action<greater_action>, const, const, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator<=, relational_action<lessorequal_action>, const, const, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator>=, relational_action<greaterorequal_action>, const, const, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator==, relational_action<equal_action>, const, const, const_copy_argument)
|
||||
BOOST_LAMBDA_BE(operator!=, relational_action<notequal_action>, const, const, const_copy_argument)
|
||||
|
||||
BOOST_LAMBDA_BE(operator+=, arithmetic_assignment_action<plus_action>, A, const B, reference_argument)
|
||||
BOOST_LAMBDA_BE(operator-=, arithmetic_assignment_action<minus_action>, A, const B, reference_argument)
|
||||
BOOST_LAMBDA_BE(operator*=, arithmetic_assignment_action<multiply_action>, A, const B, reference_argument)
|
||||
BOOST_LAMBDA_BE(operator/=, arithmetic_assignment_action<divide_action>, A, const B, reference_argument)
|
||||
BOOST_LAMBDA_BE(operator%=, arithmetic_assignment_action<remainder_action>, A, const B, reference_argument)
|
||||
BOOST_LAMBDA_BE(operator<<=, bitwise_assignment_action<leftshift_action>, A, const B, reference_argument)
|
||||
BOOST_LAMBDA_BE(operator>>=, bitwise_assignment_action<rightshift_action>, A, const B, reference_argument)
|
||||
BOOST_LAMBDA_BE(operator&=, bitwise_assignment_action<and_action>, A, const B, reference_argument)
|
||||
BOOST_LAMBDA_BE(operator|=, bitwise_assignment_action<or_action>, A, const B, reference_argument)
|
||||
BOOST_LAMBDA_BE(operator^=, bitwise_assignment_action<xor_action>, A, const B, reference_argument)
|
||||
BOOST_LAMBDA_BE(operator+=, arithmetic_assignment_action<plus_action>, , const, reference_argument)
|
||||
BOOST_LAMBDA_BE(operator-=, arithmetic_assignment_action<minus_action>, , const, reference_argument)
|
||||
BOOST_LAMBDA_BE(operator*=, arithmetic_assignment_action<multiply_action>, , const, reference_argument)
|
||||
BOOST_LAMBDA_BE(operator/=, arithmetic_assignment_action<divide_action>, , const, reference_argument)
|
||||
BOOST_LAMBDA_BE(operator%=, arithmetic_assignment_action<remainder_action>, , const, reference_argument)
|
||||
BOOST_LAMBDA_BE(operator<<=, bitwise_assignment_action<leftshift_action>, , const, reference_argument)
|
||||
BOOST_LAMBDA_BE(operator>>=, bitwise_assignment_action<rightshift_action>, , const, reference_argument)
|
||||
BOOST_LAMBDA_BE(operator&=, bitwise_assignment_action<and_action>, , const, reference_argument)
|
||||
BOOST_LAMBDA_BE(operator|=, bitwise_assignment_action<or_action>, , const, reference_argument)
|
||||
BOOST_LAMBDA_BE(operator^=, bitwise_assignment_action<xor_action>, , const, reference_argument)
|
||||
|
||||
|
||||
// A special trick for comma operator for correct preprocessing
|
||||
@@ -144,9 +139,9 @@ BOOST_LAMBDA_BE(operator^=, bitwise_assignment_action<xor_action>, A, const B, r
|
||||
|
||||
#define BOOST_LAMBDA_COMMA_OPERATOR_NAME operator,
|
||||
|
||||
BOOST_LAMBDA_BE1(BOOST_LAMBDA_COMMA_OPERATOR_NAME, other_action<comma_action>, const A, const B, const_copy_argument)
|
||||
BOOST_LAMBDA_BE2(BOOST_LAMBDA_COMMA_OPERATOR_NAME, other_action<comma_action>, const A, const B, const_copy_argument)
|
||||
BOOST_LAMBDA_BE3(BOOST_LAMBDA_COMMA_OPERATOR_NAME, other_action<comma_action>, const A, const B, const_copy_argument)
|
||||
BOOST_LAMBDA_BE1(BOOST_LAMBDA_COMMA_OPERATOR_NAME, other_action<comma_action>, const, const, const_copy_argument)
|
||||
BOOST_LAMBDA_BE2(BOOST_LAMBDA_COMMA_OPERATOR_NAME, other_action<comma_action>, const, const, const_copy_argument)
|
||||
BOOST_LAMBDA_BE3(BOOST_LAMBDA_COMMA_OPERATOR_NAME, other_action<comma_action>, const, const, const_copy_argument)
|
||||
|
||||
|
||||
|
||||
@@ -202,8 +197,8 @@ template<class T> struct convert_istream_to_ref_others_to_c_plain_by_default {
|
||||
|
||||
} // detail
|
||||
|
||||
BOOST_LAMBDA_BE2(operator<<, bitwise_action< leftshift_action>, A, const B, detail::convert_ostream_to_ref_others_to_c_plain_by_default)
|
||||
BOOST_LAMBDA_BE2(operator>>, bitwise_action< rightshift_action>, A, const B, detail::convert_istream_to_ref_others_to_c_plain_by_default)
|
||||
BOOST_LAMBDA_BE2(operator<<, bitwise_action< leftshift_action>, , const, detail::convert_ostream_to_ref_others_to_c_plain_by_default)
|
||||
BOOST_LAMBDA_BE2(operator>>, bitwise_action< rightshift_action>, , const, detail::convert_istream_to_ref_others_to_c_plain_by_default)
|
||||
|
||||
|
||||
// special case for io_manipulators.
|
||||
@@ -258,17 +253,17 @@ operator>>(const lambda_functor<Arg>& a, Ret(&b)(ManipArg))
|
||||
#error "Multiple defines of BOOST_LAMBDA_PTR_ARITHMETIC_E1"
|
||||
#endif
|
||||
|
||||
#define BOOST_LAMBDA_PTR_ARITHMETIC_E1(OPER_NAME, ACTION, CONSTB) \
|
||||
#define BOOST_LAMBDA_PTR_ARITHMETIC_E1(OPER_NAME, ACTION, CONST) \
|
||||
template<class Arg, int N, class B> \
|
||||
inline const \
|
||||
lambda_functor< \
|
||||
lambda_functor_base<ACTION, tuple<lambda_functor<Arg>, CONSTB(&)[N]> > \
|
||||
lambda_functor_base<ACTION, tuple<lambda_functor<Arg>, CONST B(&)[N]> > \
|
||||
> \
|
||||
OPER_NAME (const lambda_functor<Arg>& a, CONSTB(&b)[N]) \
|
||||
OPER_NAME (const lambda_functor<Arg>& a, CONST B(&b)[N]) \
|
||||
{ \
|
||||
return lambda_functor< \
|
||||
lambda_functor_base<ACTION, tuple<lambda_functor<Arg>, CONSTB(&)[N]> > \
|
||||
>(tuple<lambda_functor<Arg>, CONSTB(&)[N]>(a, b)); \
|
||||
lambda_functor_base<ACTION, tuple<lambda_functor<Arg>, CONST B(&)[N]> > \
|
||||
>(tuple<lambda_functor<Arg>, CONST B(&)[N]>(a, b)); \
|
||||
}
|
||||
|
||||
|
||||
@@ -276,31 +271,31 @@ OPER_NAME (const lambda_functor<Arg>& a, CONSTB(&b)[N]) \
|
||||
#error "Multiple defines of BOOST_LAMBDA_PTR_ARITHMETIC_E2"
|
||||
#endif
|
||||
|
||||
#define BOOST_LAMBDA_PTR_ARITHMETIC_E2(OPER_NAME, ACTION, CONSTA) \
|
||||
#define BOOST_LAMBDA_PTR_ARITHMETIC_E2(OPER_NAME, ACTION, CONST) \
|
||||
template<int N, class A, class Arg> \
|
||||
inline const \
|
||||
lambda_functor< \
|
||||
lambda_functor_base<ACTION, tuple<CONSTA(&)[N], lambda_functor<Arg> > > \
|
||||
lambda_functor_base<ACTION, tuple<CONST A(&)[N], lambda_functor<Arg> > > \
|
||||
> \
|
||||
OPER_NAME (CONSTA(&a)[N], const lambda_functor<Arg>& b) \
|
||||
OPER_NAME (CONST A(&a)[N], const lambda_functor<Arg>& b) \
|
||||
{ \
|
||||
return \
|
||||
lambda_functor_base<ACTION, tuple<CONSTA(&)[N], lambda_functor<Arg> > > \
|
||||
(tuple<CONSTA(&)[N], lambda_functor<Arg> >(a, b)); \
|
||||
lambda_functor_base<ACTION, tuple<CONST A(&)[N], lambda_functor<Arg> > > \
|
||||
(tuple<CONST A(&)[N], lambda_functor<Arg> >(a, b)); \
|
||||
}
|
||||
|
||||
|
||||
BOOST_LAMBDA_PTR_ARITHMETIC_E1(operator+, arithmetic_action<plus_action>, B)
|
||||
BOOST_LAMBDA_PTR_ARITHMETIC_E2(operator+, arithmetic_action<plus_action>, A)
|
||||
BOOST_LAMBDA_PTR_ARITHMETIC_E1(operator+, arithmetic_action<plus_action>,const B)
|
||||
BOOST_LAMBDA_PTR_ARITHMETIC_E2(operator+, arithmetic_action<plus_action>,const A)
|
||||
BOOST_LAMBDA_PTR_ARITHMETIC_E1(operator+, arithmetic_action<plus_action>,)
|
||||
BOOST_LAMBDA_PTR_ARITHMETIC_E2(operator+, arithmetic_action<plus_action>,)
|
||||
BOOST_LAMBDA_PTR_ARITHMETIC_E1(operator+, arithmetic_action<plus_action>,const)
|
||||
BOOST_LAMBDA_PTR_ARITHMETIC_E2(operator+, arithmetic_action<plus_action>,const)
|
||||
|
||||
|
||||
//BOOST_LAMBDA_PTR_ARITHMETIC_E1(operator-, arithmetic_action<minus_action>)
|
||||
// This is not needed, since the result of ptr-ptr is an rvalue anyway
|
||||
|
||||
BOOST_LAMBDA_PTR_ARITHMETIC_E2(operator-, arithmetic_action<minus_action>, A)
|
||||
BOOST_LAMBDA_PTR_ARITHMETIC_E2(operator-, arithmetic_action<minus_action>, const A)
|
||||
BOOST_LAMBDA_PTR_ARITHMETIC_E2(operator-, arithmetic_action<minus_action>, )
|
||||
BOOST_LAMBDA_PTR_ARITHMETIC_E2(operator-, arithmetic_action<minus_action>, const)
|
||||
|
||||
|
||||
#undef BOOST_LAMBDA_BE1
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
@@ -252,7 +257,7 @@ const_parameters(const lambda_functor<Arg>& lf)
|
||||
// the wrapped lambda functor is evaluated, but we just don't do anything
|
||||
// with the result.
|
||||
struct voidifier_action {
|
||||
template<class Ret, class A> static void apply(A&) {}
|
||||
template<class Ret, class A> static Ret apply(A&) {}
|
||||
};
|
||||
|
||||
template<class Args> struct return_type_N<voidifier_action, Args> {
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
@@ -12,8 +17,6 @@
|
||||
#ifndef BOOST_LAMBDA_RETURN_TYPE_TRAITS_HPP
|
||||
#define BOOST_LAMBDA_RETURN_TYPE_TRAITS_HPP
|
||||
|
||||
#include "boost/mpl/has_xxx.hpp"
|
||||
|
||||
#include <cstddef> // needed for the ptrdiff_t
|
||||
|
||||
namespace boost {
|
||||
@@ -236,25 +239,6 @@ struct return_type_N<function_action<I, Ret>, Args> {
|
||||
typedef Ret type;
|
||||
};
|
||||
|
||||
// ::result_type support
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
|
||||
|
||||
template<class F> struct get_result_type
|
||||
{
|
||||
typedef typename F::result_type type;
|
||||
};
|
||||
|
||||
template<class F, class A> struct get_sig
|
||||
{
|
||||
typedef typename function_adaptor<F>::template sig<A>::type type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// Ret is detail::unspecified, so try to deduce return type
|
||||
template<int I, class Args>
|
||||
struct return_type_N<function_action<I, detail::unspecified>, Args > {
|
||||
@@ -267,11 +251,7 @@ struct return_type_N<function_action<I, detail::unspecified>, Args > {
|
||||
public:
|
||||
// pass the function to function_adaptor, and get the return type from
|
||||
// that
|
||||
typedef typename detail::IF<
|
||||
detail::has_result_type<plain_Func>::value,
|
||||
detail::get_result_type<plain_Func>,
|
||||
detail::get_sig<plain_Func, Args>
|
||||
>::RET::type type;
|
||||
typedef typename function_adaptor<plain_Func>::template sig<Args>::type type;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see http://www.boost.org
|
||||
|
||||
|
||||
@@ -3,9 +3,14 @@
|
||||
// Copyright (C) 2000 Gary Powell (gwpowell@hotmail.com)
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see http://www.boost.org
|
||||
|
||||
@@ -48,7 +53,7 @@ struct try_catch_action {};
|
||||
struct throw_new_action {};
|
||||
struct rethrow_action {};
|
||||
|
||||
template<class ThrowType> struct throw_action;
|
||||
template<class ThrowType> class throw_action;
|
||||
|
||||
template<>
|
||||
struct throw_action<rethrow_action> {
|
||||
|
||||
@@ -4,9 +4,14 @@
|
||||
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
|
||||
// Copyright (C) 2001-2002 Joel de Guzman
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
@@ -319,6 +324,33 @@ public:
|
||||
// The code below is from Joel de Guzman, some name changes etc.
|
||||
// has been made.
|
||||
|
||||
/*=============================================================================
|
||||
|
||||
Copyright (c) 2001-2002 Joel de Guzman
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the copyright holder be held liable for
|
||||
any damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute
|
||||
it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
URL: http://spirit.sourceforge.net/
|
||||
|
||||
==============================================================================*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// if_then_else_composite
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
// -- lambda.hpp -- Boost Lambda Library -----------------------------------
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see http://lambda.cs.utu.fi
|
||||
|
||||
|
||||
@@ -2,11 +2,15 @@
|
||||
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
|
||||
// Copyright (c) 2001-2002 Joel de Guzman
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
@@ -261,6 +265,35 @@ public:
|
||||
// The code below is from Joel de Guzman, some name changes etc.
|
||||
// has been made.
|
||||
|
||||
/*=============================================================================
|
||||
Statements
|
||||
|
||||
Phoenix V0.9
|
||||
Copyright (c) 2001-2002 Joel de Guzman
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the copyright holder be held liable for
|
||||
any damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute
|
||||
it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
URL: http://spirit.sourceforge.net/
|
||||
|
||||
==============================================================================*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// while_composite
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
// Copyright (C) 2002 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2002 Gary Powell (gwpowell@hotmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see http://www.boost.org
|
||||
|
||||
|
||||
@@ -3,9 +3,14 @@
|
||||
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
|
||||
8
index.html
Normal file
8
index.html
Normal file
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0; URL=doc/index.html">
|
||||
</head>
|
||||
<body>
|
||||
Automatic redirection failed, please go to <a href="doc/index.html">doc/index.html</a>
|
||||
</body>
|
||||
</html>
|
||||
87
test/Jamfile
Normal file
87
test/Jamfile
Normal file
@@ -0,0 +1,87 @@
|
||||
subproject libs/lambda/test ;
|
||||
|
||||
unit-test is_instance_of_test
|
||||
: is_instance_of_test.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test operator_tests_simple
|
||||
: operator_tests_simple.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test member_pointer_test
|
||||
: member_pointer_test.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test control_structures
|
||||
: control_structures.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test switch_construct
|
||||
: switch_construct.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test bind_tests_simple
|
||||
: bind_tests_simple.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test bind_tests_advanced
|
||||
: bind_tests_advanced.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test bll_and_function
|
||||
: bll_and_function.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test constructor_tests
|
||||
: constructor_tests.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test extending_rt_traits
|
||||
: extending_rt_traits.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test bind_tests_simple_f_refs
|
||||
: bind_tests_simple_f_refs.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test cast_test
|
||||
: cast_test.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test phoenix_control_structures
|
||||
: phoenix_control_structures.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test exception_test
|
||||
: exception_test.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
|
||||
89
test/Makefile
Executable file
89
test/Makefile
Executable file
@@ -0,0 +1,89 @@
|
||||
BOOST = ../../..
|
||||
|
||||
CXX = gcc
|
||||
EXTRAFLAGS = -pedantic -Wno-long-long -ftemplate-depth-50
|
||||
LIBS = -lstdc++
|
||||
|
||||
#CXX = KCC
|
||||
#EXTRAFLAGS = --strict --display_error_number --diag_suppress 450 --max_pending_instantiations 50
|
||||
#LIBS =
|
||||
|
||||
INCLUDES = -I$(BOOST)
|
||||
|
||||
|
||||
|
||||
CXXFLAGS = $(INCLUDES) $(EXTRAFLAGS)
|
||||
|
||||
LIBFLAGS = $(LIBS)
|
||||
|
||||
|
||||
AR = ar
|
||||
|
||||
.SUFFIXES: .cpp .o
|
||||
|
||||
SOURCES = \
|
||||
is_instance_of_test.cpp \
|
||||
operator_tests_simple.cpp \
|
||||
member_pointer_test.cpp \
|
||||
control_structures.cpp \
|
||||
switch_construct.cpp \
|
||||
bind_tests_simple.cpp \
|
||||
bind_tests_advanced.cpp \
|
||||
bll_and_function.cpp \
|
||||
constructor_tests.cpp \
|
||||
extending_rt_traits.cpp \
|
||||
bind_tests_simple_f_refs.cpp \
|
||||
cast_test.cpp \
|
||||
phoenix_control_structures.cpp \
|
||||
exception_test.cpp \
|
||||
|
||||
|
||||
# Create lists of object files from the source file lists.
|
||||
|
||||
OBJECTS = ${SOURCES:.cpp=.o}
|
||||
|
||||
TARGETS = ${SOURCES:.cpp=.exe}
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
%.exe: %.o
|
||||
$(CXX) $(LIBFLAGS) $(CXXFLAGS) -o $@ $<
|
||||
|
||||
%.o: %.cpp
|
||||
$(CXX) $(CXXFLAGS) -o $@ -c $<
|
||||
|
||||
%.dep: %.cpp
|
||||
set -e; $(CXX) -M $(INCLUDES) -c $< \
|
||||
| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
|
||||
[ -s $@ ] || rm -f $@
|
||||
|
||||
DEP_FILES = $(SOURCES:.cpp=.dep)
|
||||
|
||||
include $(DEP_FILES)
|
||||
|
||||
clean:
|
||||
/bin/rm -rf $(TARGETS) $(OBJECTS) $(DEP_FILES)
|
||||
|
||||
run:
|
||||
./is_instance_of_test.exe
|
||||
./member_pointer_test.exe
|
||||
./operator_tests_simple.exe
|
||||
./control_structures.exe
|
||||
./switch_construct.exe
|
||||
./extending_rt_traits.exe
|
||||
./constructor_tests.exe
|
||||
./cast_test.exe
|
||||
./bind_tests_simple.exe
|
||||
./bind_tests_advanced.exe
|
||||
./bll_and_function.exe
|
||||
./bind_tests_simple_f_refs.exe
|
||||
./phoenix_control_structures.exe
|
||||
./exception_test.exe
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
6
test/README_gcc2.9x_users
Normal file
6
test/README_gcc2.9x_users
Normal file
@@ -0,0 +1,6 @@
|
||||
gcc 2.96
|
||||
cannot compile
|
||||
|
||||
exception_test.cpp (internal compiler error)
|
||||
|
||||
|
||||
364
test/bind_tests_advanced.cpp
Normal file
364
test/bind_tests_advanced.cpp
Normal file
@@ -0,0 +1,364 @@
|
||||
// bind_tests_advanced.cpp -- The Boost Lambda Library ------------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
#include "boost/lambda/lambda.hpp"
|
||||
#include "boost/lambda/bind.hpp"
|
||||
|
||||
|
||||
#include "boost/any.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
using namespace boost::lambda;
|
||||
|
||||
int sum_0() { return 0; }
|
||||
int sum_1(int a) { return a; }
|
||||
int sum_2(int a, int b) { return a+b; }
|
||||
|
||||
int product_2(int a, int b) { return a*b; }
|
||||
|
||||
// unary function that returns a pointer to a binary function
|
||||
typedef int (*fptr_type)(int, int);
|
||||
fptr_type sum_or_product(bool x) {
|
||||
return x ? sum_2 : product_2;
|
||||
}
|
||||
|
||||
// a nullary functor that returns a pointer to a unary function that
|
||||
// returns a pointer to a binary function.
|
||||
struct which_one {
|
||||
typedef fptr_type (*result_type)(bool x);
|
||||
template <class T> struct sig { typedef result_type type; };
|
||||
|
||||
result_type operator()() const { return sum_or_product; }
|
||||
};
|
||||
|
||||
void test_nested_binds()
|
||||
{
|
||||
int j = 2; int k = 3;
|
||||
|
||||
// bind calls can be nested (the target function can be a lambda functor)
|
||||
// The interpretation is, that the innermost lambda functor returns something
|
||||
// that is bindable (another lambda functor, function pointer ...)
|
||||
bool condition;
|
||||
|
||||
condition = true;
|
||||
BOOST_TEST(bind(bind(&sum_or_product, _1), 1, 2)(condition)==3);
|
||||
BOOST_TEST(bind(bind(&sum_or_product, _1), _2, _3)(condition, j, k)==5);
|
||||
|
||||
condition = false;
|
||||
BOOST_TEST(bind(bind(&sum_or_product, _1), 1, 2)(condition)==2);
|
||||
BOOST_TEST(bind(bind(&sum_or_product, _1), _2, _3)(condition, j, k)==6);
|
||||
|
||||
|
||||
which_one wo;
|
||||
BOOST_TEST(bind(bind(bind(wo), _1), _2, _3)(condition, j, k)==6);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// unlambda -------------------------------------------------
|
||||
|
||||
// Sometimes it may be necessary to prevent the argument substitution of
|
||||
// taking place. For example, we may end up with a nested bind expression
|
||||
// inadvertently when using the target function is received as a parameter
|
||||
|
||||
template<class F>
|
||||
int call_with_100(const F& f) {
|
||||
|
||||
|
||||
|
||||
// bind(f, _1)(make_const(100));
|
||||
// This would result in;
|
||||
// bind(_1 + 1, _1)(make_const(100)) , which would be a compile time error
|
||||
|
||||
return bind(unlambda(f), _1)(make_const(100));
|
||||
|
||||
// for other functors than lambda functors, unlambda has no effect
|
||||
// (except for making them const)
|
||||
}
|
||||
|
||||
template<class F>
|
||||
int call_with_101(const F& f) {
|
||||
|
||||
return bind(unlambda(f), _1)(make_const(101));
|
||||
|
||||
}
|
||||
|
||||
|
||||
void test_unlambda() {
|
||||
|
||||
int i = 1;
|
||||
|
||||
BOOST_TEST(unlambda(_1 + _2)(i, i) == 2);
|
||||
BOOST_TEST(unlambda(++var(i))() == 2);
|
||||
BOOST_TEST(call_with_100(_1 + 1) == 101);
|
||||
|
||||
|
||||
BOOST_TEST(call_with_101(_1 + 1) == 102);
|
||||
|
||||
BOOST_TEST(call_with_100(bind(std_functor(std::bind1st(std::plus<int>(), 1)), _1)) == 101);
|
||||
|
||||
// std_functor insturcts LL that the functor defines a result_type typedef
|
||||
// rather than a sig template.
|
||||
bind(std_functor(std::plus<int>()), _1, _2)(i, i);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// protect ------------------------------------------------------------
|
||||
|
||||
// protect protects a lambda functor from argument substitution.
|
||||
// protect is useful e.g. with nested stl algorithm calls.
|
||||
|
||||
namespace ll {
|
||||
|
||||
struct for_each {
|
||||
|
||||
// note, std::for_each returns it's last argument
|
||||
// We want the same behaviour from our ll::for_each.
|
||||
// However, the functor can be called with any arguments, and
|
||||
// the return type thus depends on the argument types.
|
||||
|
||||
// 1. Provide a sig class member template:
|
||||
|
||||
// The return type deduction system instantiate this class as:
|
||||
// sig<Args>::type, where Args is a boost::tuples::cons-list
|
||||
// The head type is the function object type itself
|
||||
// cv-qualified (so it is possilbe to provide different return types
|
||||
// for differently cv-qualified operator()'s.
|
||||
|
||||
// The tail type is the list of the types of the actual arguments the
|
||||
// function was called with.
|
||||
// So sig should contain a typedef type, which defines a mapping from
|
||||
// the operator() arguments to its return type.
|
||||
// Note, that it is possible to provide different sigs for the same functor
|
||||
// if the functor has several operator()'s, even if they have different
|
||||
// number of arguments.
|
||||
|
||||
// Note, that the argument types in Args are guaranteed to be non-reference
|
||||
// types, but they can have cv-qualifiers.
|
||||
|
||||
template <class Args>
|
||||
struct sig {
|
||||
typedef typename boost::remove_const<
|
||||
typename boost::tuples::element<3, Args>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <class A, class B, class C>
|
||||
C
|
||||
operator()(const A& a, const B& b, const C& c) const
|
||||
{ return std::for_each(a, b, c);}
|
||||
};
|
||||
|
||||
} // end of ll namespace
|
||||
|
||||
void test_protect()
|
||||
{
|
||||
int i = 0;
|
||||
int b[3][5];
|
||||
int* a[3];
|
||||
|
||||
for(int j=0; j<3; ++j) a[j] = b[j];
|
||||
|
||||
std::for_each(a, a+3,
|
||||
bind(ll::for_each(), _1, _1 + 5, protect(_1 = ++var(i))));
|
||||
|
||||
// This is how you could output the values (it is uncommented, no output
|
||||
// from a regression test file):
|
||||
// std::for_each(a, a+3,
|
||||
// bind(ll::for_each(), _1, _1 + 5,
|
||||
// std::cout << constant("\nLine ") << (&_1 - a) << " : "
|
||||
// << protect(_1)
|
||||
// )
|
||||
// );
|
||||
|
||||
int sum = 0;
|
||||
|
||||
std::for_each(a, a+3,
|
||||
bind(ll::for_each(), _1, _1 + 5,
|
||||
protect(sum += _1))
|
||||
);
|
||||
BOOST_TEST(sum == (1+15)*15/2);
|
||||
|
||||
sum = 0;
|
||||
|
||||
std::for_each(a, a+3,
|
||||
bind(ll::for_each(), _1, _1 + 5,
|
||||
sum += 1 + protect(_1)) // add element count
|
||||
);
|
||||
BOOST_TEST(sum == (1+15)*15/2 + 15);
|
||||
|
||||
(1 + protect(_1))(sum);
|
||||
|
||||
int k = 0;
|
||||
((k += constant(1)) += protect(constant(2)))();
|
||||
BOOST_TEST(k==1);
|
||||
|
||||
k = 0;
|
||||
((k += constant(1)) += protect(constant(2)))()();
|
||||
BOOST_TEST(k==3);
|
||||
|
||||
// note, the following doesn't work:
|
||||
|
||||
// ((var(k) = constant(1)) = protect(constant(2)))();
|
||||
|
||||
// (var(k) = constant(1))() returns int& and thus the
|
||||
// second assignment fails.
|
||||
|
||||
// We should have something like:
|
||||
// bind(var, var(k) = constant(1)) = protect(constant(2)))();
|
||||
// But currently var is not bindable.
|
||||
|
||||
// The same goes with ret. A bindable ret could be handy sometimes as well
|
||||
// (protect(std::cout << _1), std::cout << _1)(i)(j); does not work
|
||||
// because the comma operator tries to store the result of the evaluation
|
||||
// of std::cout << _1 as a copy (and you can't copy std::ostream).
|
||||
// something like this:
|
||||
// (protect(std::cout << _1), bind(ref, std::cout << _1))(i)(j);
|
||||
|
||||
|
||||
// the stuff below works, but we do not want extra output to
|
||||
// cout, must be changed to stringstreams but stringstreams do not
|
||||
// work due to a bug in the type deduction. Will be fixed...
|
||||
#if 0
|
||||
// But for now, ref is not bindable. There are other ways around this:
|
||||
|
||||
int x = 1, y = 2;
|
||||
(protect(std::cout << _1), (std::cout << _1, 0))(x)(y);
|
||||
|
||||
// added one dummy value to make the argument to comma an int
|
||||
// instead of ostream&
|
||||
|
||||
// Note, the same problem is more apparent without protect
|
||||
// (std::cout << 1, std::cout << constant(2))(); // does not work
|
||||
|
||||
(boost::ref(std::cout << 1), std::cout << constant(2))(); // this does
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
void test_lambda_functors_as_arguments_to_lambda_functors() {
|
||||
|
||||
// lambda functor is a function object, and can therefore be used
|
||||
// as an argument to another lambda functors function call object.
|
||||
|
||||
// Note however, that the argument/type substitution is not entered again.
|
||||
// This means, that something like this will not work:
|
||||
|
||||
(_1 + _2)(_1, make_const(7));
|
||||
(_1 + _2)(bind(&sum_0), make_const(7));
|
||||
|
||||
// or it does work, but the effect is not to call
|
||||
// sum_0() + 7, but rather
|
||||
// bind(sum_0) + 7, which results in another lambda functor
|
||||
// (lambda functor + int) and can be called again
|
||||
BOOST_TEST((_1 + _2)(bind(&sum_0), make_const(7))() == 7);
|
||||
|
||||
int i = 3, j = 12;
|
||||
BOOST_TEST((_1 - _2)(_2, _1)(i, j) == j - i);
|
||||
|
||||
// also, note that lambda functor are no special case for bind if received
|
||||
// as a parameter. In oder to be bindable, the functor must
|
||||
// defint the sig template, or then
|
||||
// the return type must be defined within the bind call. Lambda functors
|
||||
// do define the sig template, so if the return type deduction system
|
||||
// covers the case, there is no need to specify the return type
|
||||
// explicitly.
|
||||
|
||||
int a = 5, b = 6;
|
||||
|
||||
// Let type deduction find out the return type
|
||||
BOOST_TEST(bind(_1, _2, _3)(unlambda(_1 + _2), a, b) == 11);
|
||||
|
||||
//specify it yourself:
|
||||
BOOST_TEST(bind(_1, _2, _3)(ret<int>(_1 + _2), a, b) == 11);
|
||||
BOOST_TEST(ret<int>(bind(_1, _2, _3))(_1 + _2, a, b) == 11);
|
||||
BOOST_TEST(bind<int>(_1, _2, _3)(_1 + _2, a, b) == 11);
|
||||
|
||||
bind(_1,1.0)(_1+_1);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void test_const_parameters() {
|
||||
|
||||
// (_1 + _2)(1, 2); // this would fail,
|
||||
|
||||
// Either make arguments const:
|
||||
BOOST_TEST((_1 + _2)(make_const(1), make_const(2)) == 3);
|
||||
|
||||
// Or use const_parameters:
|
||||
BOOST_TEST(const_parameters(_1 + _2)(1, 2) == 3);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void test_break_const()
|
||||
{
|
||||
// break_const breaks constness! Be careful!
|
||||
// You need this only if you need to have side effects on some argument(s)
|
||||
// and some arguments are non-const rvalues:
|
||||
|
||||
// E.g.
|
||||
int i = 1;
|
||||
// (_1 += _2)(i, 2) // fails, 2 is a non-const rvalue
|
||||
|
||||
// const_parameters(_1 += _2)(i, 2) // fails, side-effect to i
|
||||
break_const(_1 += _2)(i, 2); // ok
|
||||
BOOST_TEST(i == 3);
|
||||
}
|
||||
|
||||
int test_main(int, char *[]) {
|
||||
|
||||
test_nested_binds();
|
||||
test_unlambda();
|
||||
test_protect();
|
||||
test_lambda_functors_as_arguments_to_lambda_functors();
|
||||
test_const_parameters();
|
||||
test_break_const();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
178
test/bind_tests_simple.cpp
Normal file
178
test/bind_tests_simple.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
// bind_tests_simple.cpp -- The Boost Lambda Library ------------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
#include "boost/lambda/bind.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace boost::lambda;
|
||||
|
||||
|
||||
int sum_of_args_0() { return 0; }
|
||||
int sum_of_args_1(int a) { return a; }
|
||||
int sum_of_args_2(int a, int b) { return a+b; }
|
||||
int sum_of_args_3(int a, int b, int c) { return a+b+c; }
|
||||
int sum_of_args_4(int a, int b, int c, int d) { return a+b+c+d; }
|
||||
int sum_of_args_5(int a, int b, int c, int d, int e) { return a+b+c+d+e; }
|
||||
int sum_of_args_6(int a, int b, int c, int d, int e, int f) { return a+b+c+d+e+f; }
|
||||
int sum_of_args_7(int a, int b, int c, int d, int e, int f, int g) { return a+b+c+d+e+f+g; }
|
||||
int sum_of_args_8(int a, int b, int c, int d, int e, int f, int g, int h) { return a+b+c+d+e+f+g+h; }
|
||||
int sum_of_args_9(int a, int b, int c, int d, int e, int f, int g, int h, int i) { return a+b+c+d+e+f+g+h+i; }
|
||||
|
||||
|
||||
// ----------------------------
|
||||
|
||||
class A {
|
||||
int i;
|
||||
public:
|
||||
A(int n) : i(n) {};
|
||||
int add(const int& j) { return i + j; }
|
||||
int add2(int a1, int a2) { return i + a1 + a2; }
|
||||
int add3(int a1, int a2, int a3) { return i + a1 + a2 + a3; }
|
||||
int add4(int a1, int a2, int a3, int a4) { return i + a1 + a2 + a3 + a4; }
|
||||
int add5(int a1, int a2, int a3, int a4, int a5)
|
||||
{ return i + a1 + a2 + a3 + a4 + a5; }
|
||||
int add6(int a1, int a2, int a3, int a4, int a5, int a6)
|
||||
{ return i + a1 + a2 + a3 + a4 + a5 + a6; }
|
||||
int add7(int a1, int a2, int a3, int a4, int a5, int a6, int a7)
|
||||
{ return i + a1 + a2 + a3 + a4 + a5 + a6 + a7; }
|
||||
int add8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
|
||||
{ return i + a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8; }
|
||||
|
||||
};
|
||||
|
||||
void test_member_functions()
|
||||
{
|
||||
using boost::ref;
|
||||
A a(10);
|
||||
int i = 1;
|
||||
|
||||
|
||||
|
||||
|
||||
BOOST_TEST(bind(&A::add, ref(a), _1)(i) == 11);
|
||||
BOOST_TEST(bind(&A::add, &a, _1)(i) == 11);
|
||||
BOOST_TEST(bind(&A::add, _1, 1)(a) == 11);
|
||||
BOOST_TEST(bind(&A::add, _1, 1)(make_const(&a)) == 11);
|
||||
|
||||
BOOST_TEST(bind(&A::add2, _1, 1, 1)(a) == 12);
|
||||
BOOST_TEST(bind(&A::add3, _1, 1, 1, 1)(a) == 13);
|
||||
BOOST_TEST(bind(&A::add4, _1, 1, 1, 1, 1)(a) == 14);
|
||||
BOOST_TEST(bind(&A::add5, _1, 1, 1, 1, 1, 1)(a) == 15);
|
||||
BOOST_TEST(bind(&A::add6, _1, 1, 1, 1, 1, 1, 1)(a) == 16);
|
||||
BOOST_TEST(bind(&A::add7, _1, 1, 1, 1, 1, 1, 1, 1)(a) == 17);
|
||||
BOOST_TEST(bind(&A::add8, _1, 1, 1, 1, 1, 1, 1, 1, 1)(a) == 18);
|
||||
|
||||
// This should fail, as lambda functors store arguments as const
|
||||
// bind(&A::add, a, _1);
|
||||
}
|
||||
|
||||
int test_main(int, char *[]) {
|
||||
|
||||
int i = 1; int j = 2; int k = 3;
|
||||
int result;
|
||||
|
||||
// bind all parameters
|
||||
BOOST_TEST(bind(&sum_of_args_0)()==0);
|
||||
BOOST_TEST(bind(&sum_of_args_1, 1)()==1);
|
||||
BOOST_TEST(bind(&sum_of_args_2, 1, 2)()==3);
|
||||
BOOST_TEST(bind(&sum_of_args_3, 1, 2, 3)()==6);
|
||||
BOOST_TEST(bind(&sum_of_args_4, 1, 2, 3, 4)()==10);
|
||||
BOOST_TEST(bind(&sum_of_args_5, 1, 2, 3, 4, 5)()==15);
|
||||
BOOST_TEST(bind(&sum_of_args_6, 1, 2, 3, 4, 5, 6)()==21);
|
||||
BOOST_TEST(bind(&sum_of_args_7, 1, 2, 3, 4, 5, 6, 7)()==28);
|
||||
BOOST_TEST(bind(&sum_of_args_8, 1, 2, 3, 4, 5, 6, 7, 8)()==36);
|
||||
BOOST_TEST(bind(&sum_of_args_9, 1, 2, 3, 4, 5, 6, 7, 8, 9)()==45);
|
||||
|
||||
// first parameter open
|
||||
BOOST_TEST(bind(&sum_of_args_0)()==0);
|
||||
BOOST_TEST(bind(&sum_of_args_1, _1)(i)==1);
|
||||
BOOST_TEST(bind(&sum_of_args_2, _1, 2)(i)==3);
|
||||
BOOST_TEST(bind(&sum_of_args_3, _1, 2, 3)(i)==6);
|
||||
BOOST_TEST(bind(&sum_of_args_4, _1, 2, 3, 4)(i)==10);
|
||||
BOOST_TEST(bind(&sum_of_args_5, _1, 2, 3, 4, 5)(i)==15);
|
||||
BOOST_TEST(bind(&sum_of_args_6, _1, 2, 3, 4, 5, 6)(i)==21);
|
||||
BOOST_TEST(bind(&sum_of_args_7, _1, 2, 3, 4, 5, 6, 7)(i)==28);
|
||||
BOOST_TEST(bind(&sum_of_args_8, _1, 2, 3, 4, 5, 6, 7, 8)(i)==36);
|
||||
BOOST_TEST(bind(&sum_of_args_9, _1, 2, 3, 4, 5, 6, 7, 8, 9)(i)==45);
|
||||
|
||||
// two open arguments
|
||||
BOOST_TEST(bind(&sum_of_args_0)()==0);
|
||||
BOOST_TEST(bind(&sum_of_args_1, _1)(i)==1);
|
||||
BOOST_TEST(bind(&sum_of_args_2, _1, _2)(i, j)==3);
|
||||
BOOST_TEST(bind(&sum_of_args_3, _1, _2, 3)(i, j)==6);
|
||||
BOOST_TEST(bind(&sum_of_args_4, _1, _2, 3, 4)(i, j)==10);
|
||||
BOOST_TEST(bind(&sum_of_args_5, _1, _2, 3, 4, 5)(i, j)==15);
|
||||
BOOST_TEST(bind(&sum_of_args_6, _1, _2, 3, 4, 5, 6)(i, j)==21);
|
||||
BOOST_TEST(bind(&sum_of_args_7, _1, _2, 3, 4, 5, 6, 7)(i, j)==28);
|
||||
BOOST_TEST(bind(&sum_of_args_8, _1, _2, 3, 4, 5, 6, 7, 8)(i, j)==36);
|
||||
BOOST_TEST(bind(&sum_of_args_9, _1, _2, 3, 4, 5, 6, 7, 8, 9)(i, j)==45);
|
||||
|
||||
// three open arguments
|
||||
BOOST_TEST(bind(&sum_of_args_0)()==0);
|
||||
BOOST_TEST(bind(&sum_of_args_1, _1)(i)==1);
|
||||
BOOST_TEST(bind(&sum_of_args_2, _1, _2)(i, j)==3);
|
||||
BOOST_TEST(bind(&sum_of_args_3, _1, _2, _3)(i, j, k)==6);
|
||||
BOOST_TEST(bind(&sum_of_args_4, _1, _2, _3, 4)(i, j, k)==10);
|
||||
BOOST_TEST(bind(&sum_of_args_5, _1, _2, _3, 4, 5)(i, j, k)==15);
|
||||
BOOST_TEST(bind(&sum_of_args_6, _1, _2, _3, 4, 5, 6)(i, j, k)==21);
|
||||
BOOST_TEST(bind(&sum_of_args_7, _1, _2, _3, 4, 5, 6, 7)(i, j, k)==28);
|
||||
BOOST_TEST(bind(&sum_of_args_8, _1, _2, _3, 4, 5, 6, 7, 8)(i, j, k)==36);
|
||||
BOOST_TEST(bind(&sum_of_args_9, _1, _2, _3, 4, 5, 6, 7, 8, 9)(i, j, k)==45);
|
||||
|
||||
// function compositions with bind
|
||||
BOOST_TEST(bind(&sum_of_args_3, bind(&sum_of_args_2, _1, 2), 2, 3)(i)==8);
|
||||
BOOST_TEST(
|
||||
bind(&sum_of_args_9,
|
||||
bind(&sum_of_args_0), // 0
|
||||
bind(&sum_of_args_1, _1), // 1
|
||||
bind(&sum_of_args_2, _1, _2), // 3
|
||||
bind(&sum_of_args_3, _1, _2, _3), // 6
|
||||
bind(&sum_of_args_4, _1, _2, _3, 4), // 10
|
||||
bind(&sum_of_args_5, _1, _2, _3, 4, 5), // 15
|
||||
bind(&sum_of_args_6, _1, _2, _3, 4, 5, 6), // 21
|
||||
bind(&sum_of_args_7, _1, _2, _3, 4, 5, 6, 7), // 28
|
||||
bind(&sum_of_args_8, _1, _2, _3, 4, 5, 6, 7, 8) // 36
|
||||
)(i, j, k) == 120);
|
||||
|
||||
// deeper nesting
|
||||
result =
|
||||
bind(&sum_of_args_1, // 12
|
||||
bind(&sum_of_args_4, // 12
|
||||
bind(&sum_of_args_2, // 3
|
||||
bind(&sum_of_args_1, // 1
|
||||
bind(&sum_of_args_1, _1) // 1
|
||||
),
|
||||
_2),
|
||||
_2,
|
||||
_3,
|
||||
4)
|
||||
)(i, j, k);
|
||||
BOOST_TEST(result == 12);
|
||||
|
||||
test_member_functions();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
156
test/bind_tests_simple_f_refs.cpp
Normal file
156
test/bind_tests_simple_f_refs.cpp
Normal file
@@ -0,0 +1,156 @@
|
||||
// bind_tests_simple.cpp -- The Boost Lambda Library ------------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
#include "boost/lambda/bind.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace boost::lambda;
|
||||
|
||||
|
||||
int sum_of_args_0() { return 0; }
|
||||
int sum_of_args_1(int a) { return a; }
|
||||
int sum_of_args_2(int a, int b) { return a+b; }
|
||||
int sum_of_args_3(int a, int b, int c) { return a+b+c; }
|
||||
int sum_of_args_4(int a, int b, int c, int d) { return a+b+c+d; }
|
||||
int sum_of_args_5(int a, int b, int c, int d, int e) { return a+b+c+d+e; }
|
||||
int sum_of_args_6(int a, int b, int c, int d, int e, int f) { return a+b+c+d+e+f; }
|
||||
int sum_of_args_7(int a, int b, int c, int d, int e, int f, int g) { return a+b+c+d+e+f+g; }
|
||||
int sum_of_args_8(int a, int b, int c, int d, int e, int f, int g, int h) { return a+b+c+d+e+f+g+h; }
|
||||
int sum_of_args_9(int a, int b, int c, int d, int e, int f, int g, int h, int i) { return a+b+c+d+e+f+g+h+i; }
|
||||
|
||||
|
||||
// ----------------------------
|
||||
|
||||
class A {
|
||||
int i;
|
||||
public:
|
||||
A(int n) : i(n) {};
|
||||
int add(const int& j) { return i + j; }
|
||||
};
|
||||
|
||||
void test_member_functions()
|
||||
{
|
||||
using boost::ref;
|
||||
A a(10);
|
||||
int i = 1;
|
||||
|
||||
BOOST_TEST(bind(&A::add, ref(a), _1)(i) == 11);
|
||||
BOOST_TEST(bind(&A::add, &a, _1)(i) == 11);
|
||||
BOOST_TEST(bind(&A::add, _1, 1)(a) == 11);
|
||||
BOOST_TEST(bind(&A::add, _1, 1)(make_const(&a)) == 11);
|
||||
|
||||
// This should fail, as lambda functors store arguments as const
|
||||
// bind(&A::add, a, _1);
|
||||
}
|
||||
|
||||
int test_main(int, char *[]) {
|
||||
|
||||
int i = 1; int j = 2; int k = 3;
|
||||
int result;
|
||||
|
||||
|
||||
// bind all parameters
|
||||
BOOST_TEST(bind(sum_of_args_0)()==0);
|
||||
BOOST_TEST(bind(sum_of_args_1, 1)()==1);
|
||||
BOOST_TEST(bind(sum_of_args_2, 1, 2)()==3);
|
||||
BOOST_TEST(bind(sum_of_args_3, 1, 2, 3)()==6);
|
||||
BOOST_TEST(bind(sum_of_args_4, 1, 2, 3, 4)()==10);
|
||||
BOOST_TEST(bind(sum_of_args_5, 1, 2, 3, 4, 5)()==15);
|
||||
BOOST_TEST(bind(sum_of_args_6, 1, 2, 3, 4, 5, 6)()==21);
|
||||
BOOST_TEST(bind(sum_of_args_7, 1, 2, 3, 4, 5, 6, 7)()==28);
|
||||
BOOST_TEST(bind(sum_of_args_8, 1, 2, 3, 4, 5, 6, 7, 8)()==36);
|
||||
BOOST_TEST(bind(sum_of_args_9, 1, 2, 3, 4, 5, 6, 7, 8, 9)()==45);
|
||||
|
||||
// first parameter open
|
||||
BOOST_TEST(bind(sum_of_args_0)()==0);
|
||||
BOOST_TEST(bind(sum_of_args_1, _1)(i)==1);
|
||||
BOOST_TEST(bind(sum_of_args_2, _1, 2)(i)==3);
|
||||
BOOST_TEST(bind(sum_of_args_3, _1, 2, 3)(i)==6);
|
||||
BOOST_TEST(bind(sum_of_args_4, _1, 2, 3, 4)(i)==10);
|
||||
BOOST_TEST(bind(sum_of_args_5, _1, 2, 3, 4, 5)(i)==15);
|
||||
BOOST_TEST(bind(sum_of_args_6, _1, 2, 3, 4, 5, 6)(i)==21);
|
||||
BOOST_TEST(bind(sum_of_args_7, _1, 2, 3, 4, 5, 6, 7)(i)==28);
|
||||
BOOST_TEST(bind(sum_of_args_8, _1, 2, 3, 4, 5, 6, 7, 8)(i)==36);
|
||||
BOOST_TEST(bind(sum_of_args_9, _1, 2, 3, 4, 5, 6, 7, 8, 9)(i)==45);
|
||||
|
||||
// two open arguments
|
||||
BOOST_TEST(bind(sum_of_args_0)()==0);
|
||||
BOOST_TEST(bind(sum_of_args_1, _1)(i)==1);
|
||||
BOOST_TEST(bind(sum_of_args_2, _1, _2)(i, j)==3);
|
||||
BOOST_TEST(bind(sum_of_args_3, _1, _2, 3)(i, j)==6);
|
||||
BOOST_TEST(bind(sum_of_args_4, _1, _2, 3, 4)(i, j)==10);
|
||||
BOOST_TEST(bind(sum_of_args_5, _1, _2, 3, 4, 5)(i, j)==15);
|
||||
BOOST_TEST(bind(sum_of_args_6, _1, _2, 3, 4, 5, 6)(i, j)==21);
|
||||
BOOST_TEST(bind(sum_of_args_7, _1, _2, 3, 4, 5, 6, 7)(i, j)==28);
|
||||
BOOST_TEST(bind(sum_of_args_8, _1, _2, 3, 4, 5, 6, 7, 8)(i, j)==36);
|
||||
BOOST_TEST(bind(sum_of_args_9, _1, _2, 3, 4, 5, 6, 7, 8, 9)(i, j)==45);
|
||||
|
||||
// three open arguments
|
||||
BOOST_TEST(bind(sum_of_args_0)()==0);
|
||||
BOOST_TEST(bind(sum_of_args_1, _1)(i)==1);
|
||||
BOOST_TEST(bind(sum_of_args_2, _1, _2)(i, j)==3);
|
||||
BOOST_TEST(bind(sum_of_args_3, _1, _2, _3)(i, j, k)==6);
|
||||
BOOST_TEST(bind(sum_of_args_4, _1, _2, _3, 4)(i, j, k)==10);
|
||||
BOOST_TEST(bind(sum_of_args_5, _1, _2, _3, 4, 5)(i, j, k)==15);
|
||||
BOOST_TEST(bind(sum_of_args_6, _1, _2, _3, 4, 5, 6)(i, j, k)==21);
|
||||
BOOST_TEST(bind(sum_of_args_7, _1, _2, _3, 4, 5, 6, 7)(i, j, k)==28);
|
||||
BOOST_TEST(bind(sum_of_args_8, _1, _2, _3, 4, 5, 6, 7, 8)(i, j, k)==36);
|
||||
BOOST_TEST(bind(sum_of_args_9, _1, _2, _3, 4, 5, 6, 7, 8, 9)(i, j, k)==45);
|
||||
|
||||
// function compositions with bind
|
||||
BOOST_TEST(bind(sum_of_args_3, bind(sum_of_args_2, _1, 2), 2, 3)(i)==8);
|
||||
BOOST_TEST(
|
||||
bind(sum_of_args_9,
|
||||
bind(sum_of_args_0), // 0
|
||||
bind(sum_of_args_1, _1), // 1
|
||||
bind(sum_of_args_2, _1, _2), // 3
|
||||
bind(sum_of_args_3, _1, _2, _3), // 6
|
||||
bind(sum_of_args_4, _1, _2, _3, 4), // 10
|
||||
bind(sum_of_args_5, _1, _2, _3, 4, 5), // 15
|
||||
bind(sum_of_args_6, _1, _2, _3, 4, 5, 6), // 21
|
||||
bind(sum_of_args_7, _1, _2, _3, 4, 5, 6, 7), // 28
|
||||
bind(sum_of_args_8, _1, _2, _3, 4, 5, 6, 7, 8) // 36
|
||||
)(i, j, k) == 120);
|
||||
|
||||
// deeper nesting
|
||||
result =
|
||||
bind(sum_of_args_1, // 12
|
||||
bind(sum_of_args_4, // 12
|
||||
bind(sum_of_args_2, // 3
|
||||
bind(sum_of_args_1, // 1
|
||||
bind(sum_of_args_1, _1) // 1
|
||||
),
|
||||
_2),
|
||||
_2,
|
||||
_3,
|
||||
4)
|
||||
)(i, j, k);
|
||||
BOOST_TEST(result == 12);
|
||||
|
||||
test_member_functions();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
74
test/bll_and_function.cpp
Normal file
74
test/bll_and_function.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
// bll_and_function.cpp - The Boost Lambda Library -----------------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// test using BLL and boost::function
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
#include "boost/lambda/lambda.hpp"
|
||||
|
||||
#include "boost/function.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
|
||||
using namespace boost::lambda;
|
||||
|
||||
using namespace std;
|
||||
|
||||
void test_function() {
|
||||
|
||||
boost::function<int (int, int)> f;
|
||||
f = _1 + _2;
|
||||
|
||||
BOOST_TEST(f(1, 2)== 3);
|
||||
|
||||
int i=1; int j=2;
|
||||
boost::function<int& (int&, int)> g = _1 += _2;
|
||||
g(i, j);
|
||||
BOOST_TEST(i==3);
|
||||
|
||||
|
||||
|
||||
int* sum = new int();
|
||||
*sum = 0;
|
||||
boost::function<int& (int)> counter = *sum += _1;
|
||||
counter(5); // ok, sum* = 5;
|
||||
BOOST_TEST(*sum == 5);
|
||||
delete sum;
|
||||
|
||||
// The next statement would lead to a dangling reference
|
||||
// counter(3); // error, *sum does not exist anymore
|
||||
|
||||
}
|
||||
|
||||
|
||||
int test_main(int, char *[]) {
|
||||
|
||||
test_function();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
113
test/cast_test.cpp
Normal file
113
test/cast_test.cpp
Normal file
@@ -0,0 +1,113 @@
|
||||
// cast_tests.cpp -- The Boost Lambda Library ------------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
|
||||
#include "boost/lambda/lambda.hpp"
|
||||
|
||||
#include "boost/lambda/casts.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace boost::lambda;
|
||||
using namespace std;
|
||||
|
||||
class base {
|
||||
int x;
|
||||
public:
|
||||
virtual std::string class_name() const { return "const base"; }
|
||||
virtual std::string class_name() { return "base"; }
|
||||
|
||||
};
|
||||
|
||||
class derived : public base {
|
||||
int y[100];
|
||||
public:
|
||||
virtual std::string class_name() const { return "const derived"; }
|
||||
virtual std::string class_name() { return "derived"; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
void do_test() {
|
||||
|
||||
derived *p_derived = new derived;
|
||||
base *p_base = new base;
|
||||
|
||||
base *b = 0;
|
||||
derived *d = 0;
|
||||
|
||||
(var(b) = ll_static_cast<base *>(p_derived))();
|
||||
(var(d) = ll_static_cast<derived *>(b))();
|
||||
|
||||
BOOST_TEST(b->class_name() == "derived");
|
||||
BOOST_TEST(d->class_name() == "derived");
|
||||
|
||||
(var(b) = ll_dynamic_cast<derived *>(b))();
|
||||
BOOST_TEST(b != 0);
|
||||
BOOST_TEST(b->class_name() == "derived");
|
||||
|
||||
(var(d) = ll_dynamic_cast<derived *>(p_base))();
|
||||
BOOST_TEST(d == 0);
|
||||
|
||||
|
||||
|
||||
const derived* p_const_derived = p_derived;
|
||||
|
||||
BOOST_TEST(p_const_derived->class_name() == "const derived");
|
||||
(var(d) = ll_const_cast<derived *>(p_const_derived))();
|
||||
BOOST_TEST(d->class_name() == "derived");
|
||||
|
||||
int i = 10;
|
||||
char* cp = reinterpret_cast<char*>(&i);
|
||||
|
||||
int* ip;
|
||||
(var(ip) = ll_reinterpret_cast<int *>(cp))();
|
||||
BOOST_TEST(*ip == 10);
|
||||
|
||||
|
||||
// typeid
|
||||
|
||||
BOOST_TEST(string(ll_typeid(d)().name()) == string(typeid(d).name()));
|
||||
|
||||
|
||||
// sizeof
|
||||
|
||||
BOOST_TEST(ll_sizeof(_1)(p_derived) == sizeof(p_derived));
|
||||
BOOST_TEST(ll_sizeof(_1)(*p_derived) == sizeof(*p_derived));
|
||||
BOOST_TEST(ll_sizeof(_1)(p_base) == sizeof(p_base));
|
||||
BOOST_TEST(ll_sizeof(_1)(*p_base) == sizeof(*p_base));
|
||||
|
||||
int an_array[100];
|
||||
BOOST_TEST(ll_sizeof(_1)(an_array) == 100 * sizeof(int));
|
||||
|
||||
delete p_derived;
|
||||
delete p_base;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int test_main(int, char *[]) {
|
||||
|
||||
do_test();
|
||||
return 0;
|
||||
}
|
||||
267
test/constructor_tests.cpp
Normal file
267
test/constructor_tests.cpp
Normal file
@@ -0,0 +1,267 @@
|
||||
// constructor_tests.cpp -- The Boost Lambda Library ------------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
|
||||
#include "boost/lambda/lambda.hpp"
|
||||
#include "boost/lambda/bind.hpp"
|
||||
|
||||
#include "boost/lambda/construct.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost::lambda;
|
||||
using namespace std;
|
||||
|
||||
template<class T>
|
||||
bool check_tuple(int n, const T& t)
|
||||
{
|
||||
return (t.get_head() == n) && check_tuple(n+1, t.get_tail());
|
||||
}
|
||||
|
||||
template <>
|
||||
bool check_tuple(int n, const null_type& ) { return true; }
|
||||
|
||||
|
||||
void constructor_all_lengths()
|
||||
{
|
||||
bool ok;
|
||||
ok = check_tuple(
|
||||
1,
|
||||
bind(constructor<tuple<int> >(),
|
||||
1)()
|
||||
);
|
||||
BOOST_TEST(ok);
|
||||
|
||||
ok = check_tuple(
|
||||
1,
|
||||
bind(constructor<tuple<int, int> >(),
|
||||
1, 2)()
|
||||
);
|
||||
BOOST_TEST(ok);
|
||||
|
||||
ok = check_tuple(
|
||||
1,
|
||||
bind(constructor<tuple<int, int, int> >(),
|
||||
1, 2, 3)()
|
||||
);
|
||||
BOOST_TEST(ok);
|
||||
|
||||
ok = check_tuple(
|
||||
1,
|
||||
bind(constructor<tuple<int, int, int, int> >(),
|
||||
1, 2, 3, 4)()
|
||||
);
|
||||
BOOST_TEST(ok);
|
||||
|
||||
ok = check_tuple(
|
||||
1,
|
||||
bind(constructor<tuple<int, int, int, int, int> >(),
|
||||
1, 2, 3, 4, 5)()
|
||||
);
|
||||
BOOST_TEST(ok);
|
||||
|
||||
ok = check_tuple(
|
||||
1,
|
||||
bind(constructor<tuple<int, int, int, int, int, int> >(),
|
||||
1, 2, 3, 4, 5, 6)()
|
||||
);
|
||||
BOOST_TEST(ok);
|
||||
|
||||
ok = check_tuple(
|
||||
1,
|
||||
bind(constructor<tuple<int, int, int, int, int, int, int> >(),
|
||||
1, 2, 3, 4, 5, 6, 7)()
|
||||
);
|
||||
BOOST_TEST(ok);
|
||||
|
||||
ok = check_tuple(
|
||||
1,
|
||||
bind(constructor<tuple<int, int, int, int, int, int, int, int> >(),
|
||||
1, 2, 3, 4, 5, 6, 7, 8)()
|
||||
);
|
||||
BOOST_TEST(ok);
|
||||
|
||||
ok = check_tuple(
|
||||
1,
|
||||
bind(constructor<tuple<int, int, int, int, int, int, int, int, int> >(),
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9)()
|
||||
);
|
||||
BOOST_TEST(ok);
|
||||
|
||||
}
|
||||
|
||||
void new_ptr_all_lengths()
|
||||
{
|
||||
bool ok;
|
||||
ok = check_tuple(
|
||||
1,
|
||||
*(bind(new_ptr<tuple<int> >(),
|
||||
1))()
|
||||
);
|
||||
BOOST_TEST(ok);
|
||||
|
||||
ok = check_tuple(
|
||||
1,
|
||||
*(bind(new_ptr<tuple<int, int> >(),
|
||||
1, 2))()
|
||||
);
|
||||
BOOST_TEST(ok);
|
||||
|
||||
ok = check_tuple(
|
||||
1,
|
||||
*(bind(new_ptr<tuple<int, int, int> >(),
|
||||
1, 2, 3))()
|
||||
);
|
||||
BOOST_TEST(ok);
|
||||
|
||||
ok = check_tuple(
|
||||
1,
|
||||
*(bind(new_ptr<tuple<int, int, int, int> >(),
|
||||
1, 2, 3, 4))()
|
||||
);
|
||||
BOOST_TEST(ok);
|
||||
|
||||
ok = check_tuple(
|
||||
1,
|
||||
*(bind(new_ptr<tuple<int, int, int, int, int> >(),
|
||||
1, 2, 3, 4, 5))()
|
||||
);
|
||||
BOOST_TEST(ok);
|
||||
|
||||
ok = check_tuple(
|
||||
1,
|
||||
*(bind(new_ptr<tuple<int, int, int, int, int, int> >(),
|
||||
1, 2, 3, 4, 5, 6))()
|
||||
);
|
||||
BOOST_TEST(ok);
|
||||
|
||||
ok = check_tuple(
|
||||
1,
|
||||
*(bind(new_ptr<tuple<int, int, int, int, int, int, int> >(),
|
||||
1, 2, 3, 4, 5, 6, 7))()
|
||||
);
|
||||
BOOST_TEST(ok);
|
||||
|
||||
ok = check_tuple(
|
||||
1,
|
||||
*(bind(new_ptr<tuple<int, int, int, int, int, int, int, int> >(),
|
||||
1, 2, 3, 4, 5, 6, 7, 8))()
|
||||
);
|
||||
BOOST_TEST(ok);
|
||||
|
||||
ok = check_tuple(
|
||||
1,
|
||||
*(bind(new_ptr<tuple<int, int, int, int, int, int, int, int, int> >(),
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9))()
|
||||
);
|
||||
BOOST_TEST(ok);
|
||||
|
||||
}
|
||||
|
||||
class is_destructor_called {
|
||||
bool& b;
|
||||
public:
|
||||
is_destructor_called(bool& bb) : b(bb) { b = false; }
|
||||
~is_destructor_called() { b = true; }
|
||||
};
|
||||
|
||||
void test_destructor ()
|
||||
{
|
||||
char space[sizeof(is_destructor_called)];
|
||||
bool flag;
|
||||
|
||||
is_destructor_called* idc = new(space) is_destructor_called(flag);
|
||||
BOOST_TEST(flag == false);
|
||||
bind(destructor(), _1)(idc);
|
||||
BOOST_TEST(flag == true);
|
||||
|
||||
idc = new(space) is_destructor_called(flag);
|
||||
BOOST_TEST(flag == false);
|
||||
bind(destructor(), _1)(*idc);
|
||||
BOOST_TEST(flag == true);
|
||||
}
|
||||
|
||||
|
||||
class count_deletes {
|
||||
public:
|
||||
static int count;
|
||||
~count_deletes() { ++count; }
|
||||
};
|
||||
|
||||
int count_deletes::count = 0;
|
||||
|
||||
void test_news_and_deletes ()
|
||||
{
|
||||
int* i[10];
|
||||
for_each(i, i+10, _1 = bind(new_ptr<int>(), 2));
|
||||
int count_errors = 0;
|
||||
|
||||
for_each(i, i+10, (*_1 == 2) || ++var(count_errors));
|
||||
BOOST_TEST(count_errors == 0);
|
||||
|
||||
|
||||
count_deletes* ct[10];
|
||||
for_each(ct, ct+10, _1 = bind(new_ptr<count_deletes>()));
|
||||
count_deletes::count = 0;
|
||||
for_each(ct, ct+10, bind(delete_ptr(), _1));
|
||||
BOOST_TEST(count_deletes::count == 10);
|
||||
|
||||
}
|
||||
|
||||
void test_array_new_and_delete()
|
||||
{
|
||||
count_deletes* c;
|
||||
(_1 = bind(new_array<count_deletes>(), 5))(c);
|
||||
count_deletes::count = 0;
|
||||
|
||||
bind(delete_array(), _1)(c);
|
||||
BOOST_TEST(count_deletes::count == 5);
|
||||
}
|
||||
|
||||
|
||||
void delayed_construction()
|
||||
{
|
||||
vector<int> x(3);
|
||||
vector<int> y(3);
|
||||
|
||||
fill(x.begin(), x.end(), 0);
|
||||
fill(y.begin(), y.end(), 1);
|
||||
|
||||
vector<pair<int, int> > v;
|
||||
|
||||
transform(x.begin(), x.end(), y.begin(), back_inserter(v),
|
||||
bind(constructor<pair<int, int> >(), _1, _2) );
|
||||
}
|
||||
|
||||
int test_main(int, char *[]) {
|
||||
|
||||
constructor_all_lengths();
|
||||
new_ptr_all_lengths();
|
||||
delayed_construction();
|
||||
test_destructor();
|
||||
test_news_and_deletes();
|
||||
test_array_new_and_delete();
|
||||
|
||||
return 0;
|
||||
}
|
||||
118
test/control_structures.cpp
Normal file
118
test/control_structures.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
// -- control_structures.cpp -- The Boost Lambda Library ------------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
#include "boost/lambda/lambda.hpp"
|
||||
#include "boost/lambda/if.hpp"
|
||||
#include "boost/lambda/loops.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost;
|
||||
using namespace boost::lambda;
|
||||
|
||||
// 2 container for_each
|
||||
template <class InputIter1, class InputIter2, class Function>
|
||||
Function for_each(InputIter1 first, InputIter1 last,
|
||||
InputIter2 first2, Function f) {
|
||||
for ( ; first != last; ++first, ++first2)
|
||||
f(*first, *first2);
|
||||
return f;
|
||||
}
|
||||
|
||||
void simple_loops() {
|
||||
|
||||
// for loops ---------------------------------------------------------
|
||||
int i;
|
||||
int arithmetic_series = 0;
|
||||
for_loop(_1 = 0, _1 < 10, _1++, arithmetic_series += _1)(i);
|
||||
BOOST_TEST(arithmetic_series == 45);
|
||||
|
||||
// no body case
|
||||
for_loop(var(i) = 0, var(i) < 100, ++var(i))();
|
||||
BOOST_TEST(i == 100);
|
||||
|
||||
// while loops -------------------------------------------------------
|
||||
int a = 0, b = 0, c = 0;
|
||||
|
||||
while_loop((_1 + _2) >= (_1 * _2), (++_1, ++_2, ++_3))(a, b, c);
|
||||
BOOST_TEST(c == 3);
|
||||
|
||||
int count;
|
||||
count = 0; i = 0;
|
||||
while_loop(_1++ < 10, ++var(count))(i);
|
||||
BOOST_TEST(count == 10);
|
||||
|
||||
// note that the first parameter of do_while_loop is the condition
|
||||
count = 0; i = 0;
|
||||
do_while_loop(_1++ < 10, ++var(count))(i);
|
||||
BOOST_TEST(count == 11);
|
||||
|
||||
a = 0;
|
||||
do_while_loop(constant(false), _1++)(a);
|
||||
BOOST_TEST(a == 1);
|
||||
|
||||
// no body cases
|
||||
a = 40; b = 30;
|
||||
while_loop(--_1 > _2)(a, b);
|
||||
BOOST_TEST(a == b);
|
||||
|
||||
// (the no body case for do_while_loop is pretty redundant)
|
||||
a = 40; b = 30;
|
||||
do_while_loop(--_1 > _2)(a, b);
|
||||
BOOST_TEST(a == b);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void simple_ifs () {
|
||||
|
||||
int value = 42;
|
||||
if_then(_1 < 0, _1 = 0)(value);
|
||||
BOOST_TEST(value == 42);
|
||||
|
||||
value = -42;
|
||||
if_then(_1 < 0, _1 = -_1)(value);
|
||||
BOOST_TEST(value == 42);
|
||||
|
||||
int min;
|
||||
if_then_else(_1 < _2, var(min) = _1, var(min) = _2)
|
||||
(make_const(1), make_const(2));
|
||||
BOOST_TEST(min == 1);
|
||||
|
||||
if_then_else(_1 < _2, var(min) = _1, var(min) = _2)
|
||||
(make_const(5), make_const(3));
|
||||
BOOST_TEST(min == 3);
|
||||
|
||||
int x, y;
|
||||
x = -1; y = 1;
|
||||
BOOST_TEST(if_then_else_return(_1 < _2, _2, _1)(x, y) == std::max(x ,y));
|
||||
BOOST_TEST(if_then_else_return(_1 < _2, _2, _1)(y, x) == std::max(x ,y));
|
||||
}
|
||||
|
||||
|
||||
int test_main(int, char *[])
|
||||
{
|
||||
simple_loops();
|
||||
simple_ifs();
|
||||
return 0;
|
||||
}
|
||||
627
test/exception_test.cpp
Normal file
627
test/exception_test.cpp
Normal file
@@ -0,0 +1,627 @@
|
||||
// -- exception_test.cpp -- The Boost Lambda Library ------------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
#include "boost/lambda/lambda.hpp"
|
||||
|
||||
#include "boost/lambda/exceptions.hpp"
|
||||
|
||||
#include "boost/lambda/bind.hpp"
|
||||
|
||||
#include<iostream>
|
||||
#include<algorithm>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace boost::lambda;
|
||||
using namespace std;
|
||||
|
||||
// to prevent unused variables warnings
|
||||
template <class T> void dummy(const T& t) {}
|
||||
|
||||
void erroneous_exception_related_lambda_expressions() {
|
||||
|
||||
int i = 0;
|
||||
dummy(i);
|
||||
|
||||
// Uncommenting any of the below code lines should result in a compile
|
||||
// time error
|
||||
|
||||
// this should fail (a rethrow binder outside of catch
|
||||
// rethrow()();
|
||||
|
||||
// this should fail too for the same reason
|
||||
// try_catch(rethrow(), catch_all(cout << constant("Howdy")))();
|
||||
|
||||
// this fails too (_e outside of catch_exception)
|
||||
// (_1 + _2 + _e)(i, i, i);
|
||||
|
||||
// and this (_e outside of catch_exception)
|
||||
// try_catch( throw_exception(1), catch_all(cout << _e));
|
||||
|
||||
// and this (_3 in catch_exception
|
||||
// try_catch( throw_exception(1), catch_exception<int>(cout << _3));
|
||||
}
|
||||
|
||||
|
||||
class A1 {};
|
||||
class A2 {};
|
||||
class A3 {};
|
||||
class A4 {};
|
||||
class A5 {};
|
||||
class A6 {};
|
||||
class A7 {};
|
||||
class A8 {};
|
||||
class A9 {};
|
||||
|
||||
void throw_AX(int j) {
|
||||
int i = j;
|
||||
switch(i) {
|
||||
case 1: throw A1();
|
||||
case 2: throw A2();
|
||||
case 3: throw A3();
|
||||
case 4: throw A4();
|
||||
case 5: throw A5();
|
||||
case 6: throw A6();
|
||||
case 7: throw A7();
|
||||
case 8: throw A8();
|
||||
case 9: throw A9();
|
||||
}
|
||||
}
|
||||
|
||||
void test_different_number_of_catch_blocks() {
|
||||
|
||||
int ecount;
|
||||
|
||||
// no catch(...) cases
|
||||
|
||||
|
||||
ecount = 0;
|
||||
for(int i=1; i<=1; i++)
|
||||
{
|
||||
try_catch(
|
||||
bind(throw_AX, _1),
|
||||
catch_exception<A1>(
|
||||
var(ecount)++
|
||||
)
|
||||
)(i);
|
||||
}
|
||||
BOOST_TEST(ecount == 1);
|
||||
|
||||
ecount = 0;
|
||||
for(int i=1; i<=2; i++)
|
||||
{
|
||||
try_catch(
|
||||
bind(throw_AX, _1),
|
||||
catch_exception<A1>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A2>(
|
||||
var(ecount)++
|
||||
)
|
||||
)(i);
|
||||
}
|
||||
BOOST_TEST(ecount == 2);
|
||||
|
||||
ecount = 0;
|
||||
for(int i=1; i<=3; i++)
|
||||
{
|
||||
try_catch(
|
||||
bind(throw_AX, _1),
|
||||
catch_exception<A1>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A2>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A3>(
|
||||
var(ecount)++
|
||||
)
|
||||
)(i);
|
||||
}
|
||||
BOOST_TEST(ecount == 3);
|
||||
|
||||
ecount = 0;
|
||||
for(int i=1; i<=4; i++)
|
||||
{
|
||||
try_catch(
|
||||
bind(throw_AX, _1),
|
||||
catch_exception<A1>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A2>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A3>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A4>(
|
||||
var(ecount)++
|
||||
)
|
||||
)(i);
|
||||
}
|
||||
BOOST_TEST(ecount == 4);
|
||||
|
||||
ecount = 0;
|
||||
for(int i=1; i<=5; i++)
|
||||
{
|
||||
try_catch(
|
||||
bind(throw_AX, _1),
|
||||
catch_exception<A1>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A2>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A3>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A4>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A5>(
|
||||
var(ecount)++
|
||||
)
|
||||
)(i);
|
||||
}
|
||||
BOOST_TEST(ecount == 5);
|
||||
|
||||
ecount = 0;
|
||||
for(int i=1; i<=6; i++)
|
||||
{
|
||||
try_catch(
|
||||
bind(throw_AX, _1),
|
||||
catch_exception<A1>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A2>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A3>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A4>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A5>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A6>(
|
||||
var(ecount)++
|
||||
)
|
||||
)(i);
|
||||
}
|
||||
BOOST_TEST(ecount == 6);
|
||||
|
||||
ecount = 0;
|
||||
for(int i=1; i<=7; i++)
|
||||
{
|
||||
try_catch(
|
||||
bind(throw_AX, _1),
|
||||
catch_exception<A1>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A2>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A3>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A4>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A5>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A6>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A7>(
|
||||
var(ecount)++
|
||||
)
|
||||
)(i);
|
||||
}
|
||||
BOOST_TEST(ecount == 7);
|
||||
|
||||
ecount = 0;
|
||||
for(int i=1; i<=8; i++)
|
||||
{
|
||||
try_catch(
|
||||
bind(throw_AX, _1),
|
||||
catch_exception<A1>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A2>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A3>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A4>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A5>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A6>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A7>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A8>(
|
||||
var(ecount)++
|
||||
)
|
||||
)(i);
|
||||
}
|
||||
BOOST_TEST(ecount == 8);
|
||||
|
||||
ecount = 0;
|
||||
for(int i=1; i<=9; i++)
|
||||
{
|
||||
try_catch(
|
||||
bind(throw_AX, _1),
|
||||
catch_exception<A1>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A2>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A3>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A4>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A5>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A6>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A7>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A8>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A9>(
|
||||
var(ecount)++
|
||||
)
|
||||
)(i);
|
||||
}
|
||||
BOOST_TEST(ecount == 9);
|
||||
|
||||
|
||||
// with catch(...) blocks
|
||||
|
||||
ecount = 0;
|
||||
for(int i=1; i<=1; i++)
|
||||
{
|
||||
try_catch(
|
||||
bind(throw_AX, _1),
|
||||
catch_all(
|
||||
var(ecount)++
|
||||
)
|
||||
)(i);
|
||||
}
|
||||
BOOST_TEST(ecount == 1);
|
||||
|
||||
ecount = 0;
|
||||
for(int i=1; i<=2; i++)
|
||||
{
|
||||
try_catch(
|
||||
bind(throw_AX, _1),
|
||||
catch_exception<A1>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_all(
|
||||
var(ecount)++
|
||||
)
|
||||
)(i);
|
||||
}
|
||||
BOOST_TEST(ecount == 2);
|
||||
|
||||
ecount = 0;
|
||||
for(int i=1; i<=3; i++)
|
||||
{
|
||||
try_catch(
|
||||
bind(throw_AX, _1),
|
||||
catch_exception<A1>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A2>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_all(
|
||||
var(ecount)++
|
||||
)
|
||||
)(i);
|
||||
}
|
||||
BOOST_TEST(ecount == 3);
|
||||
|
||||
ecount = 0;
|
||||
for(int i=1; i<=4; i++)
|
||||
{
|
||||
try_catch(
|
||||
bind(throw_AX, _1),
|
||||
catch_exception<A1>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A2>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A3>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_all(
|
||||
var(ecount)++
|
||||
)
|
||||
)(i);
|
||||
}
|
||||
BOOST_TEST(ecount == 4);
|
||||
|
||||
ecount = 0;
|
||||
for(int i=1; i<=5; i++)
|
||||
{
|
||||
try_catch(
|
||||
bind(throw_AX, _1),
|
||||
catch_exception<A1>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A2>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A3>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A4>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_all(
|
||||
var(ecount)++
|
||||
)
|
||||
)(i);
|
||||
}
|
||||
BOOST_TEST(ecount == 5);
|
||||
|
||||
ecount = 0;
|
||||
for(int i=1; i<=6; i++)
|
||||
{
|
||||
try_catch(
|
||||
bind(throw_AX, _1),
|
||||
catch_exception<A1>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A2>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A3>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A4>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A5>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_all(
|
||||
var(ecount)++
|
||||
)
|
||||
)(i);
|
||||
}
|
||||
BOOST_TEST(ecount == 6);
|
||||
|
||||
ecount = 0;
|
||||
for(int i=1; i<=7; i++)
|
||||
{
|
||||
try_catch(
|
||||
bind(throw_AX, _1),
|
||||
catch_exception<A1>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A2>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A3>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A4>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A5>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A6>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_all(
|
||||
var(ecount)++
|
||||
)
|
||||
)(i);
|
||||
}
|
||||
BOOST_TEST(ecount == 7);
|
||||
|
||||
ecount = 0;
|
||||
for(int i=1; i<=8; i++)
|
||||
{
|
||||
try_catch(
|
||||
bind(throw_AX, _1),
|
||||
catch_exception<A1>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A2>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A3>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A4>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A5>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A6>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A7>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_all(
|
||||
var(ecount)++
|
||||
)
|
||||
)(i);
|
||||
}
|
||||
BOOST_TEST(ecount == 8);
|
||||
|
||||
ecount = 0;
|
||||
for(int i=1; i<=9; i++)
|
||||
{
|
||||
try_catch(
|
||||
bind(throw_AX, _1),
|
||||
catch_exception<A1>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A2>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A3>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A4>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A5>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A6>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A7>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_exception<A8>(
|
||||
var(ecount)++
|
||||
),
|
||||
catch_all(
|
||||
var(ecount)++
|
||||
)
|
||||
)(i);
|
||||
}
|
||||
BOOST_TEST(ecount == 9);
|
||||
}
|
||||
|
||||
void test_empty_catch_blocks() {
|
||||
try_catch(
|
||||
bind(throw_AX, _1),
|
||||
catch_exception<A1>()
|
||||
)(make_const(1));
|
||||
|
||||
try_catch(
|
||||
bind(throw_AX, _1),
|
||||
catch_all()
|
||||
)(make_const(1));
|
||||
|
||||
}
|
||||
|
||||
|
||||
void return_type_matching() {
|
||||
|
||||
// Rules for return types of the lambda functors in try and catch parts:
|
||||
// 1. The try part dictates the return type of the whole
|
||||
// try_catch lambda functor
|
||||
// 2. If return type of try part is void, catch parts can return anything,
|
||||
// but the return types are ignored
|
||||
// 3. If the return type of the try part is A, then each catch return type
|
||||
// must be implicitly convertible to A, or then it must throw for sure
|
||||
|
||||
|
||||
int i = 1;
|
||||
|
||||
BOOST_TEST(
|
||||
|
||||
try_catch(
|
||||
_1 + 1,
|
||||
catch_exception<int>((&_1, rethrow())), // no match, but ok since throws
|
||||
catch_exception<char>(_e) // ok, char convertible to int
|
||||
)(i)
|
||||
|
||||
== 2
|
||||
);
|
||||
|
||||
// note that while e.g. char is convertible to int, it is not convertible
|
||||
// to int&, (some lambda functors return references)
|
||||
|
||||
// try_catch(
|
||||
// _1 += 1,
|
||||
// catch_exception<char>(_e) // NOT ok, char not convertible to int&
|
||||
// )(i);
|
||||
|
||||
// if you don't care about the return type, you can use make_void
|
||||
try_catch(
|
||||
make_void(_1 += 1),
|
||||
catch_exception<char>(_e) // since try is void, catch can return anything
|
||||
)(i);
|
||||
BOOST_TEST(i == 2);
|
||||
|
||||
try_catch(
|
||||
(_1 += 1, throw_exception('a')),
|
||||
catch_exception<char>(_e) // since try throws, it is void,
|
||||
// so catch can return anything
|
||||
)(i);
|
||||
BOOST_TEST(i == 3);
|
||||
|
||||
char a = 'a';
|
||||
try_catch(
|
||||
try_catch(
|
||||
throw_exception(1),
|
||||
catch_exception<int>(throw_exception('b'))
|
||||
),
|
||||
catch_exception<char>( _1 = _e )
|
||||
)(a);
|
||||
BOOST_TEST(a == 'b');
|
||||
}
|
||||
|
||||
int test_main(int, char *[]) {
|
||||
|
||||
try
|
||||
{
|
||||
test_different_number_of_catch_blocks();
|
||||
return_type_matching();
|
||||
test_empty_catch_blocks();
|
||||
}
|
||||
catch (int x)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
390
test/extending_rt_traits.cpp
Normal file
390
test/extending_rt_traits.cpp
Normal file
@@ -0,0 +1,390 @@
|
||||
// extending_return_type_traits.cpp -- The Boost Lambda Library --------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
#include "boost/lambda/bind.hpp"
|
||||
#include "boost/lambda/lambda.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
class A {};
|
||||
class B {};
|
||||
|
||||
using namespace boost::lambda;
|
||||
|
||||
|
||||
B operator--(const A&, int) { return B(); }
|
||||
B operator--(A&) { return B(); }
|
||||
B operator++(const A&, int) { return B(); }
|
||||
B operator++(A&) { return B(); }
|
||||
B operator-(const A&) { return B(); }
|
||||
B operator+(const A&) { return B(); }
|
||||
|
||||
B operator!(const A&) { return B(); }
|
||||
|
||||
B operator&(const A&) { return B(); }
|
||||
B operator*(const A&) { return B(); }
|
||||
|
||||
namespace boost {
|
||||
namespace lambda {
|
||||
|
||||
// unary + and -
|
||||
template<class Act>
|
||||
struct plain_return_type_1<unary_arithmetic_action<Act>, A > {
|
||||
typedef B type;
|
||||
};
|
||||
|
||||
// post incr/decr
|
||||
template<class Act>
|
||||
struct plain_return_type_1<post_increment_decrement_action<Act>, A > {
|
||||
typedef B type;
|
||||
};
|
||||
|
||||
// pre incr/decr
|
||||
template<class Act>
|
||||
struct plain_return_type_1<pre_increment_decrement_action<Act>, A > {
|
||||
typedef B type;
|
||||
};
|
||||
// !
|
||||
template<>
|
||||
struct plain_return_type_1<logical_action<not_action>, A> {
|
||||
typedef B type;
|
||||
};
|
||||
// &
|
||||
template<>
|
||||
struct plain_return_type_1<other_action<addressof_action>, A> {
|
||||
typedef B type;
|
||||
};
|
||||
// *
|
||||
template<>
|
||||
struct plain_return_type_1<other_action<contentsof_action>, A> {
|
||||
typedef B type;
|
||||
};
|
||||
|
||||
|
||||
} // lambda
|
||||
} // boost
|
||||
|
||||
void ok(B b) {}
|
||||
|
||||
void test_unary_operators()
|
||||
{
|
||||
A a; int i = 1;
|
||||
ok((++_1)(a));
|
||||
ok((--_1)(a));
|
||||
ok((_1++)(a));
|
||||
ok((_1--)(a));
|
||||
ok((+_1)(a));
|
||||
ok((-_1)(a));
|
||||
ok((!_1)(a));
|
||||
ok((&_1)(a));
|
||||
ok((*_1)(a));
|
||||
|
||||
BOOST_TEST((*_1)(make_const(&i)) == 1);
|
||||
}
|
||||
|
||||
class X {};
|
||||
class Y {};
|
||||
class Z {};
|
||||
|
||||
Z operator+(const X&, const Y&) { return Z(); }
|
||||
Z operator-(const X&, const Y&) { return Z(); }
|
||||
X operator*(const X&, const Y&) { return X(); }
|
||||
|
||||
Z operator/(const X&, const Y&) { return Z(); }
|
||||
Z operator%(const X&, const Y&) { return Z(); }
|
||||
|
||||
class XX {};
|
||||
class YY {};
|
||||
class ZZ {};
|
||||
class VV {};
|
||||
|
||||
// it is possible to support differently cv-qualified versions
|
||||
YY operator*(XX&, YY&) { return YY(); }
|
||||
ZZ operator*(const XX&, const YY&) { return ZZ(); }
|
||||
XX operator*(volatile XX&, volatile YY&) { return XX(); }
|
||||
VV operator*(const volatile XX&, const volatile YY&) { return VV(); }
|
||||
|
||||
// the traits can be more complex:
|
||||
template <class T>
|
||||
class my_vector {};
|
||||
|
||||
template<class A, class B>
|
||||
my_vector<typename return_type_2<arithmetic_action<plus_action>, A&, B&>::type>
|
||||
operator+(const my_vector<A>& a, const my_vector<B>& b)
|
||||
{
|
||||
typedef typename
|
||||
return_type_2<arithmetic_action<plus_action>, A&, B&>::type res_type;
|
||||
return my_vector<res_type>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// bitwise ops:
|
||||
X operator<<(const X&, const Y&) { return X(); }
|
||||
Z operator>>(const X&, const Y&) { return Z(); }
|
||||
Z operator&(const X&, const Y&) { return Z(); }
|
||||
Z operator|(const X&, const Y&) { return Z(); }
|
||||
Z operator^(const X&, const Y&) { return Z(); }
|
||||
|
||||
// comparison ops:
|
||||
|
||||
X operator<(const X&, const Y&) { return X(); }
|
||||
Z operator>(const X&, const Y&) { return Z(); }
|
||||
Z operator<=(const X&, const Y&) { return Z(); }
|
||||
Z operator>=(const X&, const Y&) { return Z(); }
|
||||
Z operator==(const X&, const Y&) { return Z(); }
|
||||
Z operator!=(const X&, const Y&) { return Z(); }
|
||||
|
||||
// logical
|
||||
|
||||
X operator&&(const X&, const Y&) { return X(); }
|
||||
Z operator||(const X&, const Y&) { return Z(); }
|
||||
|
||||
// arithh assignment
|
||||
|
||||
Z operator+=( X&, const Y&) { return Z(); }
|
||||
Z operator-=( X&, const Y&) { return Z(); }
|
||||
Y operator*=( X&, const Y&) { return Y(); }
|
||||
Z operator/=( X&, const Y&) { return Z(); }
|
||||
Z operator%=( X&, const Y&) { return Z(); }
|
||||
|
||||
// bitwise assignment
|
||||
Z operator<<=( X&, const Y&) { return Z(); }
|
||||
Z operator>>=( X&, const Y&) { return Z(); }
|
||||
Y operator&=( X&, const Y&) { return Y(); }
|
||||
Z operator|=( X&, const Y&) { return Z(); }
|
||||
Z operator^=( X&, const Y&) { return Z(); }
|
||||
|
||||
// assignment
|
||||
class Assign {
|
||||
public:
|
||||
void operator=(const Assign& a) {}
|
||||
X operator[](const int& i) { return X(); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace lambda {
|
||||
|
||||
// you can do action groups
|
||||
template<class Act>
|
||||
struct plain_return_type_2<arithmetic_action<Act>, X, Y> {
|
||||
typedef Z type;
|
||||
};
|
||||
|
||||
// or specialize the exact action
|
||||
template<>
|
||||
struct plain_return_type_2<arithmetic_action<multiply_action>, X, Y> {
|
||||
typedef X type;
|
||||
};
|
||||
|
||||
// if you want to make a distinction between differently cv-qualified
|
||||
// types, you need to specialize on a different level:
|
||||
template<>
|
||||
struct return_type_2<arithmetic_action<multiply_action>, XX, YY> {
|
||||
typedef YY type;
|
||||
};
|
||||
template<>
|
||||
struct return_type_2<arithmetic_action<multiply_action>, const XX, const YY> {
|
||||
typedef ZZ type;
|
||||
};
|
||||
template<>
|
||||
struct return_type_2<arithmetic_action<multiply_action>, volatile XX, volatile YY> {
|
||||
typedef XX type;
|
||||
};
|
||||
template<>
|
||||
struct return_type_2<arithmetic_action<multiply_action>, volatile const XX, const volatile YY> {
|
||||
typedef VV type;
|
||||
};
|
||||
|
||||
// the mapping can be more complex:
|
||||
template<class A, class B>
|
||||
struct plain_return_type_2<arithmetic_action<plus_action>, my_vector<A>, my_vector<B> > {
|
||||
typedef typename
|
||||
return_type_2<arithmetic_action<plus_action>, A&, B&>::type res_type;
|
||||
typedef my_vector<res_type> type;
|
||||
};
|
||||
|
||||
// bitwise binary:
|
||||
// you can do action groups
|
||||
template<class Act>
|
||||
struct plain_return_type_2<bitwise_action<Act>, X, Y> {
|
||||
typedef Z type;
|
||||
};
|
||||
|
||||
// or specialize the exact action
|
||||
template<>
|
||||
struct plain_return_type_2<bitwise_action<leftshift_action>, X, Y> {
|
||||
typedef X type;
|
||||
};
|
||||
|
||||
// comparison binary:
|
||||
// you can do action groups
|
||||
template<class Act>
|
||||
struct plain_return_type_2<relational_action<Act>, X, Y> {
|
||||
typedef Z type;
|
||||
};
|
||||
|
||||
// or specialize the exact action
|
||||
template<>
|
||||
struct plain_return_type_2<relational_action<less_action>, X, Y> {
|
||||
typedef X type;
|
||||
};
|
||||
|
||||
// logical binary:
|
||||
// you can do action groups
|
||||
template<class Act>
|
||||
struct plain_return_type_2<logical_action<Act>, X, Y> {
|
||||
typedef Z type;
|
||||
};
|
||||
|
||||
// or specialize the exact action
|
||||
template<>
|
||||
struct plain_return_type_2<logical_action<and_action>, X, Y> {
|
||||
typedef X type;
|
||||
};
|
||||
|
||||
// arithmetic assignment :
|
||||
// you can do action groups
|
||||
template<class Act>
|
||||
struct plain_return_type_2<arithmetic_assignment_action<Act>, X, Y> {
|
||||
typedef Z type;
|
||||
};
|
||||
|
||||
// or specialize the exact action
|
||||
template<>
|
||||
struct plain_return_type_2<arithmetic_assignment_action<multiply_action>, X, Y> {
|
||||
typedef Y type;
|
||||
};
|
||||
|
||||
// arithmetic assignment :
|
||||
// you can do action groups
|
||||
template<class Act>
|
||||
struct plain_return_type_2<bitwise_assignment_action<Act>, X, Y> {
|
||||
typedef Z type;
|
||||
};
|
||||
|
||||
// or specialize the exact action
|
||||
template<>
|
||||
struct plain_return_type_2<bitwise_assignment_action<and_action>, X, Y> {
|
||||
typedef Y type;
|
||||
};
|
||||
|
||||
// assignment
|
||||
template<>
|
||||
struct plain_return_type_2<other_action<assignment_action>, Assign, Assign> {
|
||||
typedef void type;
|
||||
};
|
||||
// subscript
|
||||
template<>
|
||||
struct plain_return_type_2<other_action<subscript_action>, Assign, int> {
|
||||
typedef X type;
|
||||
};
|
||||
|
||||
|
||||
} // end lambda
|
||||
} // end boost
|
||||
|
||||
|
||||
|
||||
void test_binary_operators() {
|
||||
|
||||
X x; Y y;
|
||||
(_1 + _2)(x, y);
|
||||
(_1 - _2)(x, y);
|
||||
(_1 * _2)(x, y);
|
||||
(_1 / _2)(x, y);
|
||||
(_1 % _2)(x, y);
|
||||
|
||||
|
||||
// make a distinction between differently cv-qualified operators
|
||||
XX xx; YY yy;
|
||||
const XX& cxx = xx;
|
||||
const YY& cyy = yy;
|
||||
volatile XX& vxx = xx;
|
||||
volatile YY& vyy = yy;
|
||||
const volatile XX& cvxx = xx;
|
||||
const volatile YY& cvyy = yy;
|
||||
|
||||
ZZ dummy1 = (_1 * _2)(cxx, cyy);
|
||||
YY dummy2 = (_1 * _2)(xx, yy);
|
||||
XX dummy3 = (_1 * _2)(vxx, vyy);
|
||||
VV dummy4 = (_1 * _2)(cvxx, cvyy);
|
||||
|
||||
my_vector<int> v1; my_vector<double> v2;
|
||||
my_vector<double> d = (_1 + _2)(v1, v2);
|
||||
|
||||
// bitwise
|
||||
|
||||
(_1 << _2)(x, y);
|
||||
(_1 >> _2)(x, y);
|
||||
(_1 | _2)(x, y);
|
||||
(_1 & _2)(x, y);
|
||||
(_1 ^ _2)(x, y);
|
||||
|
||||
// comparison
|
||||
|
||||
(_1 < _2)(x, y);
|
||||
(_1 > _2)(x, y);
|
||||
(_1 <= _2)(x, y);
|
||||
(_1 >= _2)(x, y);
|
||||
(_1 == _2)(x, y);
|
||||
(_1 != _2)(x, y);
|
||||
|
||||
// logical
|
||||
|
||||
(_1 || _2)(x, y);
|
||||
(_1 && _2)(x, y);
|
||||
|
||||
// arithmetic assignment
|
||||
(_1 += _2)(x, y);
|
||||
(_1 -= _2)(x, y);
|
||||
(_1 *= _2)(x, y);
|
||||
(_1 /= _2)(x, y);
|
||||
(_1 %= _2)(x, y);
|
||||
|
||||
// bitwise assignment
|
||||
(_1 <<= _2)(x, y);
|
||||
(_1 >>= _2)(x, y);
|
||||
(_1 |= _2)(x, y);
|
||||
(_1 &= _2)(x, y);
|
||||
(_1 ^= _2)(x, y);
|
||||
|
||||
}
|
||||
|
||||
|
||||
int test_main(int, char *[]) {
|
||||
test_unary_operators();
|
||||
test_binary_operators();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
85
test/is_instance_of_test.cpp
Normal file
85
test/is_instance_of_test.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
// is_instance_of_test.cpp -- The Boost Lambda Library ------------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
|
||||
#include "boost/lambda/detail/is_instance_of.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
template <class T1> struct A1 {};
|
||||
template <class T1, class T2> struct A2 {};
|
||||
template <class T1, class T2, class T3> struct A3 {};
|
||||
template <class T1, class T2, class T3, class T4> struct A4 {};
|
||||
|
||||
class B1 : public A1<int> {};
|
||||
class B2 : public A2<int,int> {};
|
||||
class B3 : public A3<int,int,int> {};
|
||||
class B4 : public A4<int,int,int,int> {};
|
||||
|
||||
// classes that are convertible to classes that derive from A instances
|
||||
// This is not enough to make the test succeed
|
||||
|
||||
class C1 { public: operator A1<int>() { return A1<int>(); } };
|
||||
class C2 { public: operator B2() { return B2(); } };
|
||||
class C3 { public: operator B3() { return B3(); } };
|
||||
class C4 { public: operator B4() { return B4(); } };
|
||||
|
||||
// test that the result is really a constant
|
||||
// (in an alternative implementation, gcc 3.0.2. claimed that it was
|
||||
// a non-constant)
|
||||
template <bool b> class X {};
|
||||
// this should compile
|
||||
X<boost::lambda::is_instance_of_2<int, A2>::value> x;
|
||||
|
||||
|
||||
int test_main(int, char *[]) {
|
||||
|
||||
using boost::lambda::is_instance_of_1;
|
||||
using boost::lambda::is_instance_of_2;
|
||||
using boost::lambda::is_instance_of_3;
|
||||
using boost::lambda::is_instance_of_4;
|
||||
|
||||
|
||||
BOOST_TEST((is_instance_of_1<B1, A1>::value == true));
|
||||
BOOST_TEST((is_instance_of_1<A1<float>, A1>::value == true));
|
||||
BOOST_TEST((is_instance_of_1<int, A1>::value == false));
|
||||
BOOST_TEST((is_instance_of_1<C1, A1>::value == false));
|
||||
|
||||
BOOST_TEST((is_instance_of_2<B2, A2>::value == true));
|
||||
BOOST_TEST((is_instance_of_2<A2<int, float>, A2>::value == true));
|
||||
BOOST_TEST((is_instance_of_2<int, A2>::value == false));
|
||||
BOOST_TEST((is_instance_of_2<C2, A2>::value == false));
|
||||
|
||||
BOOST_TEST((is_instance_of_3<B3, A3>::value == true));
|
||||
BOOST_TEST((is_instance_of_3<A3<int, float, char>, A3>::value == true));
|
||||
BOOST_TEST((is_instance_of_3<int, A3>::value == false));
|
||||
BOOST_TEST((is_instance_of_3<C3, A3>::value == false));
|
||||
|
||||
BOOST_TEST((is_instance_of_4<B4, A4>::value == true));
|
||||
BOOST_TEST((is_instance_of_4<A4<int, float, char, double>, A4>::value == true));
|
||||
BOOST_TEST((is_instance_of_4<int, A4>::value == false));
|
||||
BOOST_TEST((is_instance_of_4<C4, A4>::value == false));
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
198
test/member_pointer_test.cpp
Normal file
198
test/member_pointer_test.cpp
Normal file
@@ -0,0 +1,198 @@
|
||||
// member_pointer_test.cpp -- The Boost Lambda Library ------------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
|
||||
#include "boost/lambda/lambda.hpp"
|
||||
#include "boost/lambda/bind.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace boost::lambda;
|
||||
using namespace std;
|
||||
|
||||
|
||||
struct my_struct {
|
||||
my_struct(int x) : mem(x) {};
|
||||
|
||||
int mem;
|
||||
|
||||
int fooc() const { return mem; }
|
||||
int foo() { return mem; }
|
||||
int foo1c(int y) const { return y + mem; }
|
||||
int foo1(int y) { return y + mem; }
|
||||
int foo2c(int y, int x) const { return y + x + mem; }
|
||||
int foo2(int y, int x) { return y + x + mem; }
|
||||
int foo3c(int y, int x, int z) const { return y + x + z + mem; }
|
||||
int foo3(int y, int x, int z ){ return y + x + z + mem; }
|
||||
int foo4c(int a1, int a2, int a3, int a4) const { return a1+a2+a3+a4+mem; }
|
||||
int foo4(int a1, int a2, int a3, int a4){ return a1+a2+a3+a4+mem; }
|
||||
|
||||
int foo3default(int y = 1, int x = 2, int z = 3) { return y + x + z + mem; }
|
||||
};
|
||||
|
||||
my_struct x(3);
|
||||
|
||||
void pointer_to_data_member_tests() {
|
||||
|
||||
// int i = 0;
|
||||
my_struct *y = &x;
|
||||
|
||||
BOOST_TEST((_1 ->* &my_struct::mem)(y) == 3);
|
||||
|
||||
(_1 ->* &my_struct::mem)(y) = 4;
|
||||
BOOST_TEST(x.mem == 4);
|
||||
|
||||
((_1 ->* &my_struct::mem) = 5)(y);
|
||||
BOOST_TEST(x.mem == 5);
|
||||
|
||||
// &my_struct::mem is a temporary, must be constified
|
||||
((y ->* _1) = 6)(make_const(&my_struct::mem));
|
||||
BOOST_TEST(x.mem == 6);
|
||||
|
||||
((_1 ->* _2) = 7)(y, make_const(&my_struct::mem));
|
||||
BOOST_TEST(x.mem == 7);
|
||||
|
||||
}
|
||||
|
||||
void pointer_to_member_function_tests() {
|
||||
|
||||
my_struct *y = new my_struct(1);
|
||||
BOOST_TEST( (_1 ->* &my_struct::foo)(y)() == (y->mem));
|
||||
BOOST_TEST( (_1 ->* &my_struct::fooc)(y)() == (y->mem));
|
||||
BOOST_TEST( (y ->* _1)(make_const(&my_struct::foo))() == (y->mem));
|
||||
BOOST_TEST( (y ->* _1)(make_const(&my_struct::fooc))() == (y->mem));
|
||||
BOOST_TEST( (_1 ->* _2)(y, make_const(&my_struct::foo))() == (y->mem));
|
||||
BOOST_TEST( (_1 ->* _2)(y, make_const(&my_struct::fooc))() == (y->mem));
|
||||
|
||||
BOOST_TEST( (_1 ->* &my_struct::foo1)(y)(1) == (y->mem+1));
|
||||
BOOST_TEST( (_1 ->* &my_struct::foo1c)(y)(1) == (y->mem+1));
|
||||
BOOST_TEST( (y ->* _1)(make_const(&my_struct::foo1))(1) == (y->mem+1));
|
||||
BOOST_TEST( (y ->* _1)(make_const(&my_struct::foo1c))(1) == (y->mem+1));
|
||||
BOOST_TEST( (_1 ->* _2)(y, make_const(&my_struct::foo1))(1) == (y->mem+1));
|
||||
BOOST_TEST( (_1 ->* _2)(y, make_const(&my_struct::foo1c))(1) == (y->mem+1));
|
||||
|
||||
BOOST_TEST( (_1 ->* &my_struct::foo2)(y)(1,2) == (y->mem+1+2));
|
||||
BOOST_TEST( (_1 ->* &my_struct::foo2c)(y)(1,2) == (y->mem+1+2));
|
||||
BOOST_TEST( (y ->* _1)(make_const(&my_struct::foo2))(1,2) == (y->mem+1+2));
|
||||
BOOST_TEST( (y ->* _1)(make_const(&my_struct::foo2c))(1,2) == (y->mem+1+2));
|
||||
BOOST_TEST( (_1 ->* _2)(y, make_const(&my_struct::foo2))(1,2) == (y->mem+1+2));
|
||||
BOOST_TEST( (_1 ->* _2)(y, make_const(&my_struct::foo2c))(1,2) == (y->mem+1+2));
|
||||
|
||||
BOOST_TEST( (_1 ->* &my_struct::foo3)(y)(1,2,3) == (y->mem+1+2+3));
|
||||
BOOST_TEST( (_1 ->* &my_struct::foo3c)(y)(1,2,3) == (y->mem+1+2+3));
|
||||
BOOST_TEST( (y ->* _1)(make_const(&my_struct::foo3))(1,2,3) == (y->mem+1+2+3));
|
||||
BOOST_TEST( (y ->* _1)(make_const(&my_struct::foo3c))(1,2,3) == (y->mem+1+2+3));
|
||||
BOOST_TEST( (_1 ->* _2)(y, make_const(&my_struct::foo3))(1,2,3) == (y->mem+1+2+3));
|
||||
BOOST_TEST( (_1 ->* _2)(y, make_const(&my_struct::foo3c))(1,2,3) == (y->mem+1+2+3));
|
||||
|
||||
BOOST_TEST( (_1 ->* &my_struct::foo4)(y)(1,2,3,4) == (y->mem+1+2+3+4));
|
||||
BOOST_TEST( (_1 ->* &my_struct::foo4c)(y)(1,2,3,4) == (y->mem+1+2+3+4));
|
||||
BOOST_TEST( (y ->* _1)(make_const(&my_struct::foo4))(1,2,3,4) == (y->mem+1+2+3+4));
|
||||
BOOST_TEST( (y ->* _1)(make_const(&my_struct::foo4c))(1,2,3,4) == (y->mem+1+2+3+4));
|
||||
BOOST_TEST( (_1 ->* _2)(y, make_const(&my_struct::foo4))(1,2,3,4) == (y->mem+1+2+3+4));
|
||||
BOOST_TEST( (_1 ->* _2)(y, make_const(&my_struct::foo4c))(1,2,3,4) == (y->mem+1+2+3+4));
|
||||
|
||||
|
||||
|
||||
// member functions with default values do not work (inherent language issue)
|
||||
// BOOST_TEST( (_1 ->* &my_struct::foo3default)(y)() == (y->mem+1+2+3));
|
||||
|
||||
}
|
||||
|
||||
class A {};
|
||||
class B {};
|
||||
class C {};
|
||||
class D {};
|
||||
|
||||
// ->* can be overloaded to do anything
|
||||
bool operator->*(A a, B b) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator->*(B b, A a) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// let's provide specializations to take care of the return type deduction.
|
||||
// Note, that you need to provide all four cases for non-const and const
|
||||
// or use the plain_return_type_2 template.
|
||||
namespace boost {
|
||||
namespace lambda {
|
||||
|
||||
template <>
|
||||
struct return_type_2<other_action<member_pointer_action>, B, A> {
|
||||
typedef bool type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct return_type_2<other_action<member_pointer_action>, const B, A> {
|
||||
typedef bool type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct return_type_2<other_action<member_pointer_action>, B, const A> {
|
||||
typedef bool type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct return_type_2<other_action<member_pointer_action>, const B, const A> {
|
||||
typedef bool type;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
} // lambda
|
||||
} // boost
|
||||
|
||||
void test_overloaded_pointer_to_member()
|
||||
{
|
||||
A a; B b;
|
||||
|
||||
// this won't work, can't deduce the return type
|
||||
// BOOST_TEST((_1->*_2)(a, b) == false);
|
||||
|
||||
// ret<bool> gives the return type
|
||||
BOOST_TEST(ret<bool>(_1->*_2)(a, b) == false);
|
||||
BOOST_TEST(ret<bool>(a->*_1)(b) == false);
|
||||
BOOST_TEST(ret<bool>(_1->*b)(a) == false);
|
||||
BOOST_TEST((ret<bool>((var(a))->*b))() == false);
|
||||
BOOST_TEST((ret<bool>((var(a))->*var(b)))() == false);
|
||||
|
||||
|
||||
// this is ok without ret<bool> due to the return_type_2 spcialization above
|
||||
BOOST_TEST((_1->*_2)(b, a) == true);
|
||||
BOOST_TEST((b->*_1)(a) == true);
|
||||
BOOST_TEST((_1->*a)(b) == true);
|
||||
BOOST_TEST((var(b)->*a)() == true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int test_main(int, char *[]) {
|
||||
|
||||
pointer_to_data_member_tests();
|
||||
pointer_to_member_function_tests();
|
||||
test_overloaded_pointer_to_member();
|
||||
return 0;
|
||||
}
|
||||
|
||||
404
test/operator_tests_simple.cpp
Normal file
404
test/operator_tests_simple.cpp
Normal file
@@ -0,0 +1,404 @@
|
||||
// operator_tests_simple.cpp -- The Boost Lambda Library ---------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
#include "boost/lambda/lambda.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#ifndef BOOST_NO_STRINGSTREAM
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
using namespace boost::lambda;
|
||||
|
||||
|
||||
class unary_plus_tester {};
|
||||
unary_plus_tester operator+(const unary_plus_tester& a) { return a; }
|
||||
|
||||
void cout_tests()
|
||||
{
|
||||
#ifndef BOOST_NO_STRINGSTREAM
|
||||
using std::cout;
|
||||
ostringstream os;
|
||||
int i = 10;
|
||||
(os << _1)(i);
|
||||
|
||||
(os << constant("FOO"))();
|
||||
|
||||
BOOST_TEST(os.str() == std::string("10FOO"));
|
||||
|
||||
|
||||
istringstream is("ABC 1");
|
||||
std::string s;
|
||||
int k;
|
||||
|
||||
is >> s;
|
||||
is >> k;
|
||||
|
||||
BOOST_TEST(s == std::string("ABC"));
|
||||
BOOST_TEST(k == 1);
|
||||
// test for constant, constant_ref and var
|
||||
i = 5;
|
||||
constant_type<int>::type ci(constant(i));
|
||||
var_type<int>::type vi(var(i));
|
||||
|
||||
(vi = _1)(make_const(100));
|
||||
BOOST_TEST((ci)() == 5);
|
||||
BOOST_TEST(i == 100);
|
||||
|
||||
int a;
|
||||
constant_ref_type<int>::type cr(constant_ref(i));
|
||||
(++vi, var(a) = cr)();
|
||||
BOOST_TEST(i == 101);
|
||||
#endif
|
||||
}
|
||||
|
||||
void arithmetic_operators() {
|
||||
int i = 1; int j = 2; int k = 3;
|
||||
|
||||
using namespace std;
|
||||
using namespace boost::lambda;
|
||||
|
||||
BOOST_TEST((_1 + 1)(i)==2);
|
||||
BOOST_TEST(((_1 + 1) * _2)(i, j)==4);
|
||||
BOOST_TEST((_1 - 1)(i)==0);
|
||||
|
||||
BOOST_TEST((_1 * 2)(j)==4);
|
||||
BOOST_TEST((_1 / 2)(j)==1);
|
||||
|
||||
BOOST_TEST((_1 % 2)(k)==1);
|
||||
|
||||
BOOST_TEST((-_1)(i) == -1);
|
||||
BOOST_TEST((+_1)(i) == 1);
|
||||
|
||||
// test that unary plus really does something
|
||||
unary_plus_tester u;
|
||||
unary_plus_tester up = (+_1)(u);
|
||||
}
|
||||
|
||||
void bitwise_operators() {
|
||||
unsigned int ui = 2;
|
||||
|
||||
BOOST_TEST((_1 << 1)(ui)==(2 << 1));
|
||||
BOOST_TEST((_1 >> 1)(ui)==(2 >> 1));
|
||||
|
||||
BOOST_TEST((_1 & 1)(ui)==(2 & 1));
|
||||
BOOST_TEST((_1 | 1)(ui)==(2 | 1));
|
||||
BOOST_TEST((_1 ^ 1)(ui)==(2 ^ 1));
|
||||
BOOST_TEST((~_1)(ui)==~2u);
|
||||
}
|
||||
|
||||
void comparison_operators() {
|
||||
int i = 0, j = 1;
|
||||
|
||||
BOOST_TEST((_1 < _2)(i, j) == true);
|
||||
BOOST_TEST((_1 <= _2)(i, j) == true);
|
||||
BOOST_TEST((_1 == _2)(i, j) == false);
|
||||
BOOST_TEST((_1 != _2)(i, j) == true);
|
||||
BOOST_TEST((_1 > _2)(i, j) == false);
|
||||
BOOST_TEST((_1 >= _2)(i, j) == false);
|
||||
|
||||
BOOST_TEST((!(_1 < _2))(i, j) == false);
|
||||
BOOST_TEST((!(_1 <= _2))(i, j) == false);
|
||||
BOOST_TEST((!(_1 == _2))(i, j) == true);
|
||||
BOOST_TEST((!(_1 != _2))(i, j) == false);
|
||||
BOOST_TEST((!(_1 > _2))(i, j) == true);
|
||||
BOOST_TEST((!(_1 >= _2))(i, j) == true);
|
||||
}
|
||||
|
||||
void logical_operators() {
|
||||
|
||||
bool t = true, f = false;
|
||||
BOOST_TEST((_1 && _2)(t, t) == true);
|
||||
BOOST_TEST((_1 && _2)(t, f) == false);
|
||||
BOOST_TEST((_1 && _2)(f, t) == false);
|
||||
BOOST_TEST((_1 && _2)(f, f) == false);
|
||||
|
||||
BOOST_TEST((_1 || _2)(t, t) == true);
|
||||
BOOST_TEST((_1 || _2)(t, f) == true);
|
||||
BOOST_TEST((_1 || _2)(f, t) == true);
|
||||
BOOST_TEST((_1 || _2)(f, f) == false);
|
||||
|
||||
BOOST_TEST((!_1)(t) == false);
|
||||
BOOST_TEST((!_1)(f) == true);
|
||||
|
||||
// test short circuiting
|
||||
int i=0;
|
||||
|
||||
(false && ++_1)(i);
|
||||
BOOST_TEST(i==0);
|
||||
i = 0;
|
||||
|
||||
(true && ++_1)(i);
|
||||
BOOST_TEST(i==1);
|
||||
i = 0;
|
||||
|
||||
(false || ++_1)(i);
|
||||
BOOST_TEST(i==1);
|
||||
i = 0;
|
||||
|
||||
(true || ++_1)(i);
|
||||
BOOST_TEST(i==0);
|
||||
i = 0;
|
||||
}
|
||||
|
||||
void unary_incs_and_decs() {
|
||||
int i = 0;
|
||||
|
||||
BOOST_TEST(_1++(i) == 0);
|
||||
BOOST_TEST(i == 1);
|
||||
i = 0;
|
||||
|
||||
BOOST_TEST(_1--(i) == 0);
|
||||
BOOST_TEST(i == -1);
|
||||
i = 0;
|
||||
|
||||
BOOST_TEST((++_1)(i) == 1);
|
||||
BOOST_TEST(i == 1);
|
||||
i = 0;
|
||||
|
||||
BOOST_TEST((--_1)(i) == -1);
|
||||
BOOST_TEST(i == -1);
|
||||
i = 0;
|
||||
|
||||
// the result of prefix -- and ++ are lvalues
|
||||
(++_1)(i) = 10;
|
||||
BOOST_TEST(i==10);
|
||||
i = 0;
|
||||
|
||||
(--_1)(i) = 10;
|
||||
BOOST_TEST(i==10);
|
||||
i = 0;
|
||||
}
|
||||
|
||||
void compound_operators() {
|
||||
|
||||
int i = 1;
|
||||
|
||||
// normal variable as the left operand
|
||||
(i += _1)(make_const(1));
|
||||
BOOST_TEST(i == 2);
|
||||
|
||||
(i -= _1)(make_const(1));
|
||||
BOOST_TEST(i == 1);
|
||||
|
||||
(i *= _1)(make_const(10));
|
||||
BOOST_TEST(i == 10);
|
||||
|
||||
(i /= _1)(make_const(2));
|
||||
BOOST_TEST(i == 5);
|
||||
|
||||
(i %= _1)(make_const(2));
|
||||
BOOST_TEST(i == 1);
|
||||
|
||||
// lambda expression as a left operand
|
||||
(_1 += 1)(i);
|
||||
BOOST_TEST(i == 2);
|
||||
|
||||
(_1 -= 1)(i);
|
||||
BOOST_TEST(i == 1);
|
||||
|
||||
(_1 *= 10)(i);
|
||||
BOOST_TEST(i == 10);
|
||||
|
||||
(_1 /= 2)(i);
|
||||
BOOST_TEST(i == 5);
|
||||
|
||||
(_1 %= 2)(i);
|
||||
BOOST_TEST(i == 1);
|
||||
|
||||
// shifts
|
||||
unsigned int ui = 2;
|
||||
(_1 <<= 1)(ui);
|
||||
BOOST_TEST(ui==(2 << 1));
|
||||
|
||||
ui = 2;
|
||||
(_1 >>= 1)(ui);
|
||||
BOOST_TEST(ui==(2 >> 1));
|
||||
|
||||
ui = 2;
|
||||
(ui <<= _1)(make_const(1));
|
||||
BOOST_TEST(ui==(2 << 1));
|
||||
|
||||
ui = 2;
|
||||
(ui >>= _1)(make_const(1));
|
||||
BOOST_TEST(ui==(2 >> 1));
|
||||
|
||||
// and, or, xor
|
||||
ui = 2;
|
||||
(_1 &= 1)(ui);
|
||||
BOOST_TEST(ui==(2 & 1));
|
||||
|
||||
ui = 2;
|
||||
(_1 |= 1)(ui);
|
||||
BOOST_TEST(ui==(2 | 1));
|
||||
|
||||
ui = 2;
|
||||
(_1 ^= 1)(ui);
|
||||
BOOST_TEST(ui==(2 ^ 1));
|
||||
|
||||
ui = 2;
|
||||
(ui &= _1)(make_const(1));
|
||||
BOOST_TEST(ui==(2 & 1));
|
||||
|
||||
ui = 2;
|
||||
(ui |= _1)(make_const(1));
|
||||
BOOST_TEST(ui==(2 | 1));
|
||||
|
||||
ui = 2;
|
||||
(ui ^= _1)(make_const(1));
|
||||
BOOST_TEST(ui==(2 ^ 1));
|
||||
|
||||
}
|
||||
|
||||
void assignment_and_subscript() {
|
||||
|
||||
// assignment and subscript need to be defined as member functions.
|
||||
// Hence, if you wish to use a normal variable as the left hand argument,
|
||||
// you must wrap it with var to turn it into a lambda expression
|
||||
|
||||
using std::string;
|
||||
string s;
|
||||
|
||||
(_1 = "one")(s);
|
||||
BOOST_TEST(s == string("one"));
|
||||
|
||||
(var(s) = "two")();
|
||||
BOOST_TEST(s == string("two"));
|
||||
|
||||
BOOST_TEST((var(s)[_1])(make_const(2)) == 'o');
|
||||
BOOST_TEST((_1[2])(s) == 'o');
|
||||
BOOST_TEST((_1[_2])(s, make_const(2)) == 'o');
|
||||
|
||||
// subscript returns lvalue
|
||||
(var(s)[_1])(make_const(1)) = 'o';
|
||||
BOOST_TEST(s == "too");
|
||||
|
||||
(_1[1])(s) = 'a';
|
||||
BOOST_TEST(s == "tao");
|
||||
|
||||
(_1[_2])(s, make_const(0)) = 'm';
|
||||
BOOST_TEST(s == "mao");
|
||||
|
||||
// TODO: tests for vector, set, map, multimap
|
||||
}
|
||||
|
||||
class A {};
|
||||
|
||||
void address_of_and_dereference() {
|
||||
|
||||
A a; int i = 42;
|
||||
|
||||
BOOST_TEST((&_1)(a) == &a);
|
||||
BOOST_TEST((*&_1)(i) == 42);
|
||||
|
||||
std::vector<int> vi; vi.push_back(1);
|
||||
std::vector<int>::iterator it = vi.begin();
|
||||
|
||||
(*_1 = 7)(it);
|
||||
BOOST_TEST(vi[0] == 7);
|
||||
|
||||
// TODO: Add tests for more complex iterator types
|
||||
}
|
||||
|
||||
|
||||
|
||||
void comma() {
|
||||
|
||||
int i = 100;
|
||||
BOOST_TEST((_1 = 10, 2 * _1)(i) == 20);
|
||||
|
||||
// TODO: that the return type is the exact type of the right argument
|
||||
// (that r/l valueness is preserved)
|
||||
|
||||
}
|
||||
|
||||
void pointer_arithmetic() {
|
||||
|
||||
int ia[4] = { 1, 2, 3, 4 };
|
||||
int* ip = ia;
|
||||
int* ia_last = &ia[3];
|
||||
|
||||
const int cia[4] = { 1, 2, 3, 4 };
|
||||
const int* cip = cia;
|
||||
const int* cia_last = &cia[3];
|
||||
|
||||
|
||||
// non-const array
|
||||
BOOST_TEST((*(_1 + 1))(ia) == 2);
|
||||
|
||||
// non-const pointer
|
||||
BOOST_TEST((*(_1 + 1))(ip) == 2);
|
||||
|
||||
BOOST_TEST((*(_1 - 1))(ia_last) == 3);
|
||||
|
||||
// const array
|
||||
BOOST_TEST((*(_1 + 1))(cia) == 2);
|
||||
// const pointer
|
||||
BOOST_TEST((*(_1 + 1))(cip) == 2);
|
||||
BOOST_TEST((*(_1 - 1))(cia_last) == 3);
|
||||
|
||||
// pointer arithmetic should not make non-consts const
|
||||
(*(_1 + 2))(ia) = 0;
|
||||
(*(_1 + 3))(ip) = 0;
|
||||
|
||||
BOOST_TEST(ia[2] == 0);
|
||||
BOOST_TEST(ia[3] == 0);
|
||||
|
||||
// pointer - pointer
|
||||
BOOST_TEST((_1 - _2)(ia_last, ia) == 3);
|
||||
BOOST_TEST((_1 - _2)(cia_last, cia) == 3);
|
||||
BOOST_TEST((ia_last - _1)(ia) == 3);
|
||||
BOOST_TEST((cia_last - _1)(cia) == 3);
|
||||
BOOST_TEST((cia_last - _1)(cip) == 3);
|
||||
|
||||
}
|
||||
|
||||
int test_main(int, char *[]) {
|
||||
|
||||
arithmetic_operators();
|
||||
bitwise_operators();
|
||||
comparison_operators();
|
||||
logical_operators();
|
||||
unary_incs_and_decs();
|
||||
compound_operators();
|
||||
assignment_and_subscript();
|
||||
address_of_and_dereference();
|
||||
comma();
|
||||
pointer_arithmetic();
|
||||
cout_tests();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
154
test/phoenix_control_structures.cpp
Normal file
154
test/phoenix_control_structures.cpp
Normal file
@@ -0,0 +1,154 @@
|
||||
// phoenix_style_control_structures.cpp -- The Boost Lambda Library ------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
#include "boost/lambda/lambda.hpp"
|
||||
#include "boost/lambda/if.hpp"
|
||||
#include "boost/lambda/loops.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
|
||||
|
||||
|
||||
using namespace boost::lambda;
|
||||
using namespace std;
|
||||
|
||||
|
||||
|
||||
// If-else, while, do-while, for statements
|
||||
|
||||
|
||||
int test_main(int, char *[]) {
|
||||
|
||||
vector<int> v;
|
||||
v.clear();
|
||||
v.push_back(1);
|
||||
v.push_back(2);
|
||||
v.push_back(3);
|
||||
v.push_back(4);
|
||||
v.push_back(5);
|
||||
v.push_back(6);
|
||||
v.push_back(7);
|
||||
v.push_back(8);
|
||||
v.push_back(9);
|
||||
v.push_back(10);
|
||||
|
||||
int sum = 0;
|
||||
//////////////////////////////////
|
||||
for_each(v.begin(), v.end(),
|
||||
if_(_1 > 3 && _1 <= 8)
|
||||
[
|
||||
sum += _1
|
||||
]
|
||||
);
|
||||
|
||||
BOOST_TEST(sum == 4+5+6+7+8);
|
||||
|
||||
int gt = 0, eq = 0, lt = 0;
|
||||
//////////////////////////////////
|
||||
for_each(v.begin(), v.end(),
|
||||
if_(_1 > 5)
|
||||
[
|
||||
++var(gt)
|
||||
]
|
||||
.else_
|
||||
[
|
||||
if_(_1 == 5)
|
||||
[
|
||||
++var(eq)
|
||||
]
|
||||
.else_
|
||||
[
|
||||
++var(lt)
|
||||
]
|
||||
]
|
||||
);
|
||||
|
||||
BOOST_TEST(lt==4);
|
||||
BOOST_TEST(eq==1);
|
||||
BOOST_TEST(gt==5);
|
||||
|
||||
vector<int> t = v;
|
||||
|
||||
int counta = 0;
|
||||
int countb = 0;
|
||||
//////////////////////////////////
|
||||
for_each(v.begin(), v.end(),
|
||||
(
|
||||
while_(_1--)
|
||||
[
|
||||
++var(counta)
|
||||
],
|
||||
++var(countb)
|
||||
)
|
||||
);
|
||||
|
||||
BOOST_TEST(counta == 55);
|
||||
BOOST_TEST(countb == 10);
|
||||
|
||||
|
||||
v = t;
|
||||
|
||||
counta = 0; countb = 0;
|
||||
//////////////////////////////////
|
||||
for_each(v.begin(), v.end(),
|
||||
(
|
||||
do_
|
||||
[
|
||||
++var(counta)
|
||||
]
|
||||
.while_(_1--),
|
||||
++var(countb)
|
||||
)
|
||||
);
|
||||
|
||||
BOOST_TEST(counta == (2+11)*10/2);
|
||||
BOOST_TEST(countb == 10);
|
||||
|
||||
|
||||
v = t;
|
||||
counta = 0; countb = 0;
|
||||
//////////////////////////////////
|
||||
int iii;
|
||||
for_each(v.begin(), v.end(),
|
||||
(
|
||||
for_(var(iii) = 0, var(iii) < _1, ++var(iii))
|
||||
[
|
||||
++var(counta)
|
||||
],
|
||||
++var(countb)
|
||||
)
|
||||
);
|
||||
|
||||
BOOST_TEST(counta == (1+10)*10/2);
|
||||
BOOST_TEST(countb == 10);
|
||||
|
||||
v = t;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
398
test/switch_construct.cpp
Normal file
398
test/switch_construct.cpp
Normal file
@@ -0,0 +1,398 @@
|
||||
// switch_test.cpp -- The Boost Lambda Library --------------------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
|
||||
#include "boost/lambda/lambda.hpp"
|
||||
#include "boost/lambda/if.hpp"
|
||||
#include "boost/lambda/switch.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
||||
// Check that elements 0 -- index are 1, and the rest are 0
|
||||
bool check(const std::vector<int>& v, int index) {
|
||||
using namespace boost::lambda;
|
||||
int counter = 0;
|
||||
std::vector<int>::const_iterator
|
||||
result = std::find_if(v.begin(), v.end(),
|
||||
! if_then_else_return(
|
||||
var(counter)++ <= index,
|
||||
_1 == 1,
|
||||
_1 == 0)
|
||||
);
|
||||
return result == v.end();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void do_switch_no_defaults_tests() {
|
||||
|
||||
using namespace boost::lambda;
|
||||
|
||||
int i = 0;
|
||||
std::vector<int> v,w;
|
||||
|
||||
// elements from 0 to 9
|
||||
std::generate_n(std::back_inserter(v),
|
||||
10,
|
||||
var(i)++);
|
||||
std::fill_n(std::back_inserter(w), 10, 0);
|
||||
|
||||
// ---
|
||||
std::for_each(v.begin(), v.end(),
|
||||
switch_statement(
|
||||
_1,
|
||||
case_statement<0>(++var(w[0]))
|
||||
)
|
||||
);
|
||||
|
||||
BOOST_TEST(check(w, 0));
|
||||
std::fill_n(w.begin(), 10, 0);
|
||||
|
||||
// ---
|
||||
std::for_each(v.begin(), v.end(),
|
||||
switch_statement(
|
||||
_1,
|
||||
case_statement<0>(++var(w[0])),
|
||||
case_statement<1>(++var(w[1]))
|
||||
)
|
||||
);
|
||||
|
||||
BOOST_TEST(check(w, 1));
|
||||
std::fill_n(w.begin(), 10, 0);
|
||||
|
||||
// ---
|
||||
std::for_each(v.begin(), v.end(),
|
||||
switch_statement(
|
||||
_1,
|
||||
case_statement<0>(++var(w[0])),
|
||||
case_statement<1>(++var(w[1])),
|
||||
case_statement<2>(++var(w[2]))
|
||||
)
|
||||
);
|
||||
|
||||
BOOST_TEST(check(w, 2));
|
||||
std::fill_n(w.begin(), 10, 0);
|
||||
|
||||
// ---
|
||||
std::for_each(v.begin(), v.end(),
|
||||
switch_statement(
|
||||
_1,
|
||||
case_statement<0>(++var(w[0])),
|
||||
case_statement<1>(++var(w[1])),
|
||||
case_statement<2>(++var(w[2])),
|
||||
case_statement<3>(++var(w[3]))
|
||||
)
|
||||
);
|
||||
|
||||
BOOST_TEST(check(w, 3));
|
||||
std::fill_n(w.begin(), 10, 0);
|
||||
|
||||
// ---
|
||||
std::for_each(v.begin(), v.end(),
|
||||
switch_statement(
|
||||
_1,
|
||||
case_statement<0>(++var(w[0])),
|
||||
case_statement<1>(++var(w[1])),
|
||||
case_statement<2>(++var(w[2])),
|
||||
case_statement<3>(++var(w[3])),
|
||||
case_statement<4>(++var(w[4]))
|
||||
)
|
||||
);
|
||||
|
||||
BOOST_TEST(check(w, 4));
|
||||
std::fill_n(w.begin(), 10, 0);
|
||||
|
||||
// ---
|
||||
std::for_each(v.begin(), v.end(),
|
||||
switch_statement(
|
||||
_1,
|
||||
case_statement<0>(++var(w[0])),
|
||||
case_statement<1>(++var(w[1])),
|
||||
case_statement<2>(++var(w[2])),
|
||||
case_statement<3>(++var(w[3])),
|
||||
case_statement<4>(++var(w[4])),
|
||||
case_statement<5>(++var(w[5]))
|
||||
)
|
||||
);
|
||||
|
||||
BOOST_TEST(check(w, 5));
|
||||
std::fill_n(w.begin(), 10, 0);
|
||||
|
||||
// ---
|
||||
std::for_each(v.begin(), v.end(),
|
||||
switch_statement(
|
||||
_1,
|
||||
case_statement<0>(++var(w[0])),
|
||||
case_statement<1>(++var(w[1])),
|
||||
case_statement<2>(++var(w[2])),
|
||||
case_statement<3>(++var(w[3])),
|
||||
case_statement<4>(++var(w[4])),
|
||||
case_statement<5>(++var(w[5])),
|
||||
case_statement<6>(++var(w[6]))
|
||||
)
|
||||
);
|
||||
|
||||
BOOST_TEST(check(w, 6));
|
||||
std::fill_n(w.begin(), 10, 0);
|
||||
|
||||
// ---
|
||||
std::for_each(v.begin(), v.end(),
|
||||
switch_statement(
|
||||
_1,
|
||||
case_statement<0>(++var(w[0])),
|
||||
case_statement<1>(++var(w[1])),
|
||||
case_statement<2>(++var(w[2])),
|
||||
case_statement<3>(++var(w[3])),
|
||||
case_statement<4>(++var(w[4])),
|
||||
case_statement<5>(++var(w[5])),
|
||||
case_statement<6>(++var(w[6])),
|
||||
case_statement<7>(++var(w[7]))
|
||||
)
|
||||
);
|
||||
|
||||
BOOST_TEST(check(w, 7));
|
||||
std::fill_n(w.begin(), 10, 0);
|
||||
|
||||
// ---
|
||||
std::for_each(v.begin(), v.end(),
|
||||
switch_statement(
|
||||
_1,
|
||||
case_statement<0>(++var(w[0])),
|
||||
case_statement<1>(++var(w[1])),
|
||||
case_statement<2>(++var(w[2])),
|
||||
case_statement<3>(++var(w[3])),
|
||||
case_statement<4>(++var(w[4])),
|
||||
case_statement<5>(++var(w[5])),
|
||||
case_statement<6>(++var(w[6])),
|
||||
case_statement<7>(++var(w[7])),
|
||||
case_statement<8>(++var(w[8]))
|
||||
)
|
||||
);
|
||||
|
||||
BOOST_TEST(check(w, 8));
|
||||
std::fill_n(w.begin(), 10, 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void do_switch_yes_defaults_tests() {
|
||||
|
||||
using namespace boost::lambda;
|
||||
|
||||
int i = 0;
|
||||
std::vector<int> v,w;
|
||||
|
||||
// elements from 0 to 9
|
||||
std::generate_n(std::back_inserter(v),
|
||||
10,
|
||||
var(i)++);
|
||||
std::fill_n(std::back_inserter(w), 10, 0);
|
||||
|
||||
int default_count;
|
||||
// ---
|
||||
default_count = 0;
|
||||
std::for_each(v.begin(), v.end(),
|
||||
switch_statement(
|
||||
_1,
|
||||
default_statement(++var(default_count))
|
||||
)
|
||||
);
|
||||
|
||||
BOOST_TEST(check(w, -1));
|
||||
BOOST_TEST(default_count == 10);
|
||||
std::fill_n(w.begin(), 10, 0);
|
||||
|
||||
// ---
|
||||
default_count = 0;
|
||||
std::for_each(v.begin(), v.end(),
|
||||
switch_statement(
|
||||
_1,
|
||||
case_statement<0>(++var(w[0])),
|
||||
default_statement(++var(default_count))
|
||||
)
|
||||
);
|
||||
|
||||
BOOST_TEST(check(w, 0));
|
||||
BOOST_TEST(default_count == 9);
|
||||
std::fill_n(w.begin(), 10, 0);
|
||||
|
||||
// ---
|
||||
default_count = 0;
|
||||
std::for_each(v.begin(), v.end(),
|
||||
switch_statement(
|
||||
_1,
|
||||
case_statement<0>(++var(w[0])),
|
||||
case_statement<1>(++var(w[1])),
|
||||
default_statement(++var(default_count))
|
||||
)
|
||||
);
|
||||
|
||||
BOOST_TEST(check(w, 1));
|
||||
BOOST_TEST(default_count == 8);
|
||||
std::fill_n(w.begin(), 10, 0);
|
||||
|
||||
// ---
|
||||
default_count = 0;
|
||||
std::for_each(v.begin(), v.end(),
|
||||
switch_statement(
|
||||
_1,
|
||||
case_statement<0>(++var(w[0])),
|
||||
case_statement<1>(++var(w[1])),
|
||||
case_statement<2>(++var(w[2])),
|
||||
default_statement(++var(default_count))
|
||||
)
|
||||
);
|
||||
|
||||
BOOST_TEST(check(w, 2));
|
||||
BOOST_TEST(default_count == 7);
|
||||
std::fill_n(w.begin(), 10, 0);
|
||||
|
||||
// ---
|
||||
default_count = 0;
|
||||
std::for_each(v.begin(), v.end(),
|
||||
switch_statement(
|
||||
_1,
|
||||
case_statement<0>(++var(w[0])),
|
||||
case_statement<1>(++var(w[1])),
|
||||
case_statement<2>(++var(w[2])),
|
||||
case_statement<3>(++var(w[3])),
|
||||
default_statement(++var(default_count))
|
||||
)
|
||||
);
|
||||
|
||||
BOOST_TEST(check(w, 3));
|
||||
BOOST_TEST(default_count == 6);
|
||||
std::fill_n(w.begin(), 10, 0);
|
||||
|
||||
// ---
|
||||
default_count = 0;
|
||||
std::for_each(v.begin(), v.end(),
|
||||
switch_statement(
|
||||
_1,
|
||||
case_statement<0>(++var(w[0])),
|
||||
case_statement<1>(++var(w[1])),
|
||||
case_statement<2>(++var(w[2])),
|
||||
case_statement<3>(++var(w[3])),
|
||||
case_statement<4>(++var(w[4])),
|
||||
default_statement(++var(default_count))
|
||||
)
|
||||
);
|
||||
|
||||
BOOST_TEST(check(w, 4));
|
||||
BOOST_TEST(default_count == 5);
|
||||
std::fill_n(w.begin(), 10, 0);
|
||||
|
||||
// ---
|
||||
default_count = 0;
|
||||
std::for_each(v.begin(), v.end(),
|
||||
switch_statement(
|
||||
_1,
|
||||
case_statement<0>(++var(w[0])),
|
||||
case_statement<1>(++var(w[1])),
|
||||
case_statement<2>(++var(w[2])),
|
||||
case_statement<3>(++var(w[3])),
|
||||
case_statement<4>(++var(w[4])),
|
||||
case_statement<5>(++var(w[5])),
|
||||
default_statement(++var(default_count))
|
||||
)
|
||||
);
|
||||
|
||||
BOOST_TEST(check(w, 5));
|
||||
BOOST_TEST(default_count == 4);
|
||||
std::fill_n(w.begin(), 10, 0);
|
||||
|
||||
// ---
|
||||
default_count = 0;
|
||||
std::for_each(v.begin(), v.end(),
|
||||
switch_statement(
|
||||
_1,
|
||||
case_statement<0>(++var(w[0])),
|
||||
case_statement<1>(++var(w[1])),
|
||||
case_statement<2>(++var(w[2])),
|
||||
case_statement<3>(++var(w[3])),
|
||||
case_statement<4>(++var(w[4])),
|
||||
case_statement<5>(++var(w[5])),
|
||||
case_statement<6>(++var(w[6])),
|
||||
default_statement(++var(default_count))
|
||||
)
|
||||
);
|
||||
|
||||
BOOST_TEST(check(w, 6));
|
||||
BOOST_TEST(default_count == 3);
|
||||
std::fill_n(w.begin(), 10, 0);
|
||||
|
||||
// ---
|
||||
default_count = 0;
|
||||
std::for_each(v.begin(), v.end(),
|
||||
switch_statement(
|
||||
_1,
|
||||
case_statement<0>(++var(w[0])),
|
||||
case_statement<1>(++var(w[1])),
|
||||
case_statement<2>(++var(w[2])),
|
||||
case_statement<3>(++var(w[3])),
|
||||
case_statement<4>(++var(w[4])),
|
||||
case_statement<5>(++var(w[5])),
|
||||
case_statement<6>(++var(w[6])),
|
||||
case_statement<7>(++var(w[7])),
|
||||
default_statement(++var(default_count))
|
||||
)
|
||||
);
|
||||
|
||||
BOOST_TEST(check(w, 7));
|
||||
BOOST_TEST(default_count == 2);
|
||||
std::fill_n(w.begin(), 10, 0);
|
||||
|
||||
}
|
||||
|
||||
void test_empty_cases() {
|
||||
|
||||
using namespace boost::lambda;
|
||||
|
||||
// ---
|
||||
switch_statement(
|
||||
_1,
|
||||
default_statement()
|
||||
)(make_const(1));
|
||||
|
||||
switch_statement(
|
||||
_1,
|
||||
case_statement<1>()
|
||||
)(make_const(1));
|
||||
|
||||
}
|
||||
|
||||
int test_main(int, char* []) {
|
||||
|
||||
do_switch_no_defaults_tests();
|
||||
do_switch_yes_defaults_tests();
|
||||
|
||||
test_empty_cases();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user