2
0
mirror of https://github.com/boostorg/lambda.git synced 2026-01-21 17:02:36 +00:00

Compare commits

..

4 Commits

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

[SVN r15904]
2002-10-11 15:17:55 +00:00
Jaakko Järvi
ae0ed56337 bugfix
[SVN r15887]
2002-10-10 22:04:40 +00:00
Jaakko Järvi
0323ca1876 fixed a bug in example code
[SVN r15576]
2002-09-30 20:40:07 +00:00
nobody
4227c144de This commit was manufactured by cvs2svn to create branch 'RC_1_29_0'.
[SVN r15460]
2002-09-19 20:49:39 +00:00
75 changed files with 6485 additions and 6064 deletions

View File

@@ -1,40 +0,0 @@
# Copyright 2016 Edward Diener
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
language: cpp
sudo: false
python: "2.7"
os:
- linux
- osx
branches:
only:
- master
- develop
install:
- cd ..
- git clone -b $TRAVIS_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule update --init tools/build
- git submodule update --init libs/config
- git submodule update --init tools/boostdep
- cp -r $TRAVIS_BUILD_DIR/* libs/lambda
- python tools/boostdep/depinst/depinst.py lambda
- ./bootstrap.sh
- ./b2 headers
script:
- TOOLSET=gcc,clang
- if [ $TRAVIS_OS_NAME == osx ]; then TOOLSET=clang; fi
- ./b2 --verbose-test libs/config/test//config_info toolset=$TOOLSET || true
- ./b2 libs/lambda/test toolset=$TOOLSET
notifications:
email:
on_success: always

View File

@@ -1,36 +0,0 @@
# Copyright 2017 Edward Diener
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
version: 1.0.{build}-{branch}
shallow_clone: true
branches:
only:
- master
- develop
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0,msvc-12.0,msvc-14.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc-14.1
install:
- cd ..
- git clone -b %APPVEYOR_REPO_BRANCH% https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule update --init tools/build
- git submodule update --init libs/config
- git submodule update --init tools/boostdep
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\lambda
- python tools/boostdep/depinst/depinst.py lambda
- bootstrap
- b2 headers
build: off
test_script:
- b2 libs/lambda/test toolset=%TOOLSET%

View File

@@ -1,21 +0,0 @@
project lambda/doc ;
import boostbook : boostbook ;
# Are these really the correct images??
path-constant images : ../../spirit/phoenix/doc/html ;
boostbook lambda-doc : lambda.xml
:
<xsl:param>boost.root=../../../..
<format>pdf:<xsl:param>img.src.path=$(images)/
;
###############################################################################
alias boostdoc
: lambda.xml
:
:
: ;
explicit boostdoc ;
alias boostrelease ;
explicit boostrelease ;

61
doc/apa.html Normal file
View 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="id2808831"></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
View 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="id2790109"></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="id2741935"></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
View 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="id2741982"></a>3. Introduction</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2741989"></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 &lt;class T&gt; : public binary_function&lt;T, T, T&gt;
struct plus {
T operator()(const T&amp; i, const T&amp; j) const {
return i + j;
}
};
</pre>
The base class <tt>binary_function&lt;T, T, T&gt;</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&amp; i) : _i(i) {}
int operator()(const int&amp; 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&lt;int&gt;(), 1)
</pre>
The subexpression <tt>plus&lt;int&gt;()</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&lt;int&gt;(cout),
bind1st(plus&lt;int&gt;(), 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&lt;int&gt;(cout),
1 + _1);
</pre>
or even more intuitively:
<pre class="programlisting">
for_each(a.begin(), a.end(), cout &lt;&lt; (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="id2742784"></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
View 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&lt;int&gt; 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="id2739587" href="#ftn.id2739587">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&lt;int*&gt; vp(10);
transform(v.begin(), v.end(), vp.begin(), &amp;_1);</pre>
The expression <tt>&amp;_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 &gt; *_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 &lt;&lt; *_1 &lt;&lt; '\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 &lt;&lt; '\n' &lt;&lt; *_1);
</pre>
the subexpression <tt>cout &lt;&lt; '\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 &lt;&lt; constant('\n') &lt;&lt; *_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&lt;C&gt;(_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&lt;int&gt;(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>&lt;&lt;</tt> or <tt>&gt;&gt;</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.id2739587" href="#id2739587">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

File diff suppressed because it is too large Load Diff

207
doc/ar01s06.html Normal file
View 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&lt;Action, A&gt;
</tt>
and
<tt>
return_type_1&lt;Action, A&gt;
</tt>, and
<tt>
plain_return_type_2&lt;Action, A, B&gt;
</tt>
and
<tt>
return_type_2&lt;Action, A, B&gt;
</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&lt;plus_action&gt;</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&amp;, const Y&amp;);
Z operator-(const X&amp;, const Y&amp;);
</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&lt;class Act&gt;
struct plain_return_type_2&lt;arithmetic_action&lt;Act&gt;, X, Y&gt; {
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&amp;, const Y&amp;);
</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&lt;&gt;
struct plain_return_type_2&lt;arithmetic_action&lt;multiply_action&gt;, X, Y&gt; {
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 &lt;class T&gt; 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&lt;int&gt;</tt> and
<tt>my_vector&lt;double&gt;</tt> results in
<tt>my_vector&lt;double&gt;</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&lt;class A, class B&gt;
my_vector&lt;typename return_type_2&lt;arithmetic_action&lt;plus_action&gt;, A, B&gt;::type&gt;
operator+(const my_vector&lt;A&gt;&amp; a, const my_vector&lt;B&gt;&amp; b)
{
typedef typename
return_type_2&lt;arithmetic_action&lt;plus_action&gt;, A, B&gt;::type res_type;
return my_vector&lt;res_type&gt;();
}
</pre>
</p><p>
To allow BLL to deduce the type of <tt>my_vector</tt>
additions correctly, we can define:
<pre class="programlisting">
template&lt;class A, class B&gt;
class plain_return_type_2&lt;arithmetic_action&lt;plus_action&gt;,
my_vector&lt;A&gt;, my_vector&lt;B&gt; &gt; {
typedef typename
return_type_2&lt;arithmetic_action&lt;plus_action&gt;, A, B&gt;::type res_type;
public:
typedef my_vector&lt;res_type&gt; 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&lt;plus_action&gt;</tt></td></tr><tr><td><tt>-</tt></td><td><tt>arithmetic_action&lt;minus_action&gt;</tt></td></tr><tr><td><tt>*</tt></td><td><tt>arithmetic_action&lt;multiply_action&gt;</tt></td></tr><tr><td><tt>/</tt></td><td><tt>arithmetic_action&lt;divide_action&gt;</tt></td></tr><tr><td><tt>%</tt></td><td><tt>arithmetic_action&lt;remainder_action&gt;</tt></td></tr><tr><td><tt>+</tt></td><td><tt>unary_arithmetic_action&lt;plus_action&gt;</tt></td></tr><tr><td><tt>-</tt></td><td><tt>unary_arithmetic_action&lt;minus_action&gt;</tt></td></tr><tr><td><tt>&amp;</tt></td><td><tt>bitwise_action&lt;and_action&gt;</tt></td></tr><tr><td><tt>|</tt></td><td><tt>bitwise_action&lt;or_action&gt;</tt></td></tr><tr><td><tt>~</tt></td><td><tt>bitwise_action&lt;not_action&gt;</tt></td></tr><tr><td><tt>^</tt></td><td><tt>bitwise_action&lt;xor_action&gt;</tt></td></tr><tr><td><tt>&lt;&lt;</tt></td><td><tt>bitwise_action&lt;leftshift_action_no_stream&gt;</tt></td></tr><tr><td><tt>&gt;&gt;</tt></td><td><tt>bitwise_action&lt;rightshift_action_no_stream&gt;</tt></td></tr><tr><td><tt>&amp;&amp;</tt></td><td><tt>logical_action&lt;and_action&gt;</tt></td></tr><tr><td><tt>||</tt></td><td><tt>logical_action&lt;or_action&gt;</tt></td></tr><tr><td><tt>!</tt></td><td><tt>logical_action&lt;not_action&gt;</tt></td></tr><tr><td><tt>&lt;</tt></td><td><tt>relational_action&lt;less_action&gt;</tt></td></tr><tr><td><tt>&gt;</tt></td><td><tt>relational_action&lt;greater_action&gt;</tt></td></tr><tr><td><tt>&lt;=</tt></td><td><tt>relational_action&lt;lessorequal_action&gt;</tt></td></tr><tr><td><tt>&gt;=</tt></td><td><tt>relational_action&lt;greaterorequal_action&gt;</tt></td></tr><tr><td><tt>==</tt></td><td><tt>relational_action&lt;equal_action&gt;</tt></td></tr><tr><td><tt>!=</tt></td><td><tt>relational_action&lt;notequal_action&gt;</tt></td></tr><tr><td><tt>+=</tt></td><td><tt>arithmetic_assignment_action&lt;plus_action&gt;</tt></td></tr><tr><td><tt>-=</tt></td><td><tt>arithmetic_assignment_action&lt;minus_action&gt;</tt></td></tr><tr><td><tt>*=</tt></td><td><tt>arithmetic_assignment_action&lt;multiply_action&gt;</tt></td></tr><tr><td><tt>/=</tt></td><td><tt>arithmetic_assignment_action&lt;divide_action&gt;</tt></td></tr><tr><td><tt>%=</tt></td><td><tt>arithmetic_assignment_action&lt;remainder_action&gt;</tt></td></tr><tr><td><tt>&amp;=</tt></td><td><tt>bitwise_assignment_action&lt;and_action&gt;</tt></td></tr><tr><td><tt>=|</tt></td><td><tt>bitwise_assignment_action&lt;or_action&gt;</tt></td></tr><tr><td><tt>^=</tt></td><td><tt>bitwise_assignment_action&lt;xor_action&gt;</tt></td></tr><tr><td><tt>&lt;&lt;=</tt></td><td><tt>bitwise_assignment_action&lt;leftshift_action&gt;</tt></td></tr><tr><td><tt>&gt;&gt;=</tt></td><td><tt>bitwise_assignment_action&lt;rightshift_action&gt;</tt></td></tr><tr><td><tt>++</tt></td><td><tt>pre_increment_decrement_action&lt;increment_action&gt;</tt></td></tr><tr><td><tt>--</tt></td><td><tt>pre_increment_decrement_action&lt;decrement_action&gt;</tt></td></tr><tr><td><tt>++</tt></td><td><tt>post_increment_decrement_action&lt;increment_action&gt;</tt></td></tr><tr><td><tt>--</tt></td><td><tt>post_increment_decrement_action&lt;decrement_action&gt;</tt></td></tr><tr><td><tt>&amp;</tt></td><td><tt>other_action&lt;address_of_action&gt;</tt></td></tr><tr><td><tt>*</tt></td><td><tt>other_action&lt;contents_of_action&gt;</tt></td></tr><tr><td><tt>,</tt></td><td><tt>other_action&lt;comma_action&gt;</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
View 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="id2807557"></a>7. Practical considerations</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2807564"></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&lt;int&gt;</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 experiensed
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="id2808056"></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="id2808118"></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="id2808157"></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
View 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="id2808502"></a>8. Relation to other Boost libraries</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2808509"></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&lt;int(int, int)&gt; f = _1 + _2;
boost::function&lt;int&amp;(int&amp;)&gt; 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&lt;int&amp;(int)&gt; 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="id2808613"></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="id2808678"></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&lt;class F&gt;
int foo(const F&amp; 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
View 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="id2808810"></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
View 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="id2808983" class="bibliography"><div class="titlepage"><div><h2 class="title"><a name="id2808983"></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 &#8211; 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>

View File

@@ -2,6 +2,6 @@
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
- lambda_doc.html loads stylesheets that generate one big html-file
(you need to edit the paths in these files to make them work)

215
doc/detail/lambda_doc.xml Normal file → Executable file
View File

@@ -1,42 +1,54 @@
<?xml version="1.0" encoding="ISO-Latin-1"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
<library name="Lambda" dirname="lambda" id="lambda"
last-revision="$Date$"
xmlns:xi="http://www.w3.org/2001/XInclude">
<libraryinfo>
<author>
<firstname>Jaakko</firstname>
<surname>Järvi</surname>
<email>jarvi at cs tamu edu</email>
</author>
<?xml version='1.0' encoding="ISO-Latin-1" ?>
<!DOCTYPE article
PUBLIC "-//OASIS//DTD DocBook XML MathML V4.1.2//EN"
"/u/jajarvi/dtd/docbook-xml/docbookx.dtd"
>
<article>
<articleinfo>
<title>
<inlinemediaobject>
<imageobject>
<imagedata fileref="../../../c++boost.gif" format="gif"/>
</imageobject>
<textobject>
<phrase>C++ BOOST</phrase>
</textobject>
</inlinemediaobject>
<copyright>
<year>1999</year>
<year>2000</year>
<year>2001</year>
<year>2002</year>
<year>2003</year>
<year>2004</year>
<holder>Jaakko Järvi</holder>
<holder>Gary Powell</holder>
</copyright>
The Boost Lambda Library</title>
<!-- <author>
<surname>Järvi</surname><firstname>Jaakko</firstname>
<affiliation>
<legalnotice>
<para>Use, modification and distribution is subject to the Boost
Software License, Version 1.0. (See accompanying file
<filename>LICENSE_1_0.txt</filename> or copy at <ulink
url="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</ulink>)</para>
</legalnotice>
<orgname>Indiana University</orgname>
<orgdiv></orgdiv>
</affiliation>
</author>
-->
<orgname>BOOST</orgname>
<copyright>
<year>1999-2002</year>
<holder>Jaakko Järvi</holder>
<holder>Gary Powell</holder>
</copyright>
<legalnotice>
<para>
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.
</para>
</legalnotice>
</articleinfo>
<librarypurpose>Define small unnamed function objects at the actual call site, and more</librarypurpose>
<librarycategory name="category:higher-order"/>
</libraryinfo>
<!-- -->
<section id="introduction">
<title>In a nutshell</title>
<para>
@@ -163,8 +175,8 @@ The STL contains predefined function objects for some common cases (such as <lit
As an example, one possible implementation for the standard <literal>plus</literal> template is:
<programlisting>
<![CDATA[template <class T>
struct plus : public binary_function<T, T, T> {
<![CDATA[template <class T> : public binary_function<T, T, T>
struct plus {
T operator()(const T& i, const T& j) const {
return i + j;
}
@@ -542,11 +554,6 @@ These functions are described more thoroughly in <xref linkend="sect:delaying_co
<section id="sect:actual_arguments_to_lambda_functors">
<title>About actual arguments to lambda functors</title>
<para><emphasis>This section is no longer (or currently) relevant;
acual arguments can be non-const rvalues.
The section can, however, become relevant again, if in the future BLL will support
lambda functors with higher arities than 3.</emphasis></para>
<para>A general restriction for the actual arguments is that they cannot be non-const rvalues.
For example:
@@ -580,18 +587,19 @@ 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:
<programlisting>
int i = 1;
(_1 = 2, _1 + i)(i);
(_1 + i)(i = 2);
</programlisting>
The comma operator is overloaded to combine lambda expressions into a sequence;
the resulting unary lambda functor first assigns 2 to its argument,
then adds the value of <literal>i</literal> to it.
The value of the expression in the last line is 3, not 4.
In other words, the lambda expression that is created is
<literal>lambda x.(x = 2, x + 1)</literal> rather than
<literal>lambda x.(x = 2, x + i)</literal>.
In other words, the lambda expression <literal>_1 + i</literal> creates
a lambda function <literal>lambda x.x+1</literal> rather than
<literal>lambda x.x+i</literal>.
</para>
@@ -615,12 +623,12 @@ or as a reference to const respectively.
For example, if we rewrite the previous example and wrap the variable
<literal>i</literal> with <literal>ref</literal>,
we are creating the lambda expression <literal>lambda x.(x = 2, x + i)</literal>
we are creating the lambda expression <literal>lambda x.x+i</literal>
and the value of the expression in the last line will be 4:
<programlisting>
i = 1;
(_1 = 2, _1 + ref(i))(i);
(_1 + ref(i))(i = 2);
</programlisting>
Note that <literal>ref</literal> and <literal>cref</literal> are different
@@ -1148,46 +1156,18 @@ operator defined, can be used as target functions.
In general, BLL cannot deduce the return type of an arbitrary function object.
However, there are two methods for giving BLL this capability for a certain
However, there is a method for giving BLL this capability for a certain
function object class.
</para>
<simplesect>
<title>The result_type typedef</title>
<para>
The BLL supports the standard library convention of declaring the return type
of a function object with a member typedef named <literal>result_type</literal> in the
function object class.
Here is a simple example:
<programlisting>
<![CDATA[struct A {
typedef B result_type;
B operator()(X, Y, Z);
};]]>
</programlisting>
If a function object does not define a <literal>result_type</literal> typedef,
the method described below (<literal>sig</literal> template)
is attempted to resolve the return type of the
function object. If a function object defines both <literal>result_type</literal>
and <literal>sig</literal>, <literal>result_type</literal> takes precedence.
</para>
</simplesect>
<simplesect>
<title>The sig template</title>
<para>
Another mechanism that make BLL aware of the return type(s) of a function object is defining
member template struct
To make BLL aware of the return type(s) of a function object one needs to
provide a member template struct
<literal><![CDATA[sig<Args>]]></literal> with a typedef
<literal>type</literal> that specifies the return type.
@@ -1206,7 +1186,9 @@ is the function
object type itself, and the remaining elements are the types of
the arguments, with which the function object is being called.
This may seem overly complex compared to defining the <literal>result_type</literal> typedef.
This may seem overly complex compared to the Standard Library
convention for defining the return type of a function
object with the <literal>return_type</literal> typedef.
Howver, there are two significant restrictions with using just a simple
typedef to express the return type:
<orderedlist>
@@ -1281,6 +1263,27 @@ mechanism first introduced in the FC++ library
</simplesect>
<para>
Earlier versions of the library supported the Standard Library convention
as the default, and required special actions to make the library recognize
the <literal>sig</literal> template.
Now the BLL has that reversed.
If one needs to use a functor that adheres to the Standard Library
convention in a bind expression, we provide the <literal>std_functor</literal>
wrapper, that gives the function object a <literal>sig</literal>
template based on the <literal>result_type</literal> typedef.
For example:
<programlisting>
<![CDATA[int i = 1;
bind(plus<int>(), _1, 1)(i); // error, no sig template
bind(std_functor(plus<int>()), _1, 1)(i); // ok]]>
</programlisting>
</para>
</section>
@@ -1589,7 +1592,7 @@ For example, using this syntax the <literal>if_then</literal> example above
can be written as:
<programlisting>
<![CDATA[for_each(a.begin(), a.end(),
if_(_1 % 2 == 0)[ cout << _1 ])]]>
if(_1 % 2 == 0)[ cout << _1 ])]]>
</programlisting>
As more experience is gained, we may end up deprecating one or the other
@@ -1854,7 +1857,7 @@ and the effect of evaluating that expression.
</row>
<row>
<entry><literal>destructor()(pa)</literal></entry>
<entry><literal>pa->~A()</literal>, where <literal>pa</literal> is of type <literal>A*</literal></entry>
<entry><literal>pa.->A()</literal>, where <literal>pa</literal> is of type <literal>A*</literal></entry>
</row>
<row>
<entry><literal>new_ptr&lt;T&gt;()(<parameter>arg_list</parameter>)</literal></entry>
@@ -2071,13 +2074,6 @@ was to allow nested STL algorithm invocations
<section id="sect:rvalues_as_actual_arguments">
<title>Rvalues as actual arguments to lambda functors</title>
<para><emphasis>This section and all of its subsections
are no longer (or currently) relevant;
acual arguments can be non-const rvalues and these workarounds are thus
not needed.
The section can, however, become relevant again, if in the future BLL will support
lambda functors with higher arities than 3.</emphasis></para>
<para>
Actual arguments to the lambda functors cannot be non-const rvalues.
This is due to a deliberate design decision: either we have this restriction,
@@ -2724,7 +2720,7 @@ Note however, that evaluating a lambda functor consist of a sequence of calls to
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
Although the above tests do not include such an expression, we have experiensed
this for some seemingly simple expressions.
@@ -2878,7 +2874,7 @@ at compile time, and being slow to compile.
<listitem>
<para>
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 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.
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.
</para>
</listitem>
@@ -3037,8 +3033,8 @@ For example:
<![CDATA[boost::function<int(int, int)> f = _1 + _2;
boost::function<int&(int&)> g = (_1 += 10);
int i = 1, j = 2;
f(i, j); // returns 3
g(i); // sets i to = 11;]]>
f(i); // returns 3
g(i); // sets i to = 11;]]>
</programlisting>
The return and parameter types of the wrapped function object must be written explicilty as the template argument to the wrapper template <literal>boost::function</literal>; even when lambda functors, which otherwise have generic parameters, are wrapped.
@@ -3353,37 +3349,6 @@ was dropped.
<bibliomisc><ulink url="http://www.oonumerics.org/tmpw01/">www.oonumerics.org/tmpw01/</ulink></bibliomisc>
</biblioentry>
<biblioentry id="cit:jarvi:03">
<abbrev>Jär03</abbrev>
<articleinfo>
<author>
<surname>Järvi</surname>
<firstname>Jaakko</firstname>
</author>
<author>
<firstname>Gary</firstname>
<surname>Powell</surname>
</author>
<author>
<firstname>Andrew</firstname>
<surname>Lumsdaine</surname>
</author>
<title>The Lambda Library : unnamed functions in C++</title>
</articleinfo>
<title>Software - Practice and Expreience</title>
<volumenum>33:259-291</volumenum>
<pubdate>2003</pubdate>
</biblioentry>
<biblioentry id="cit:boost::tuple">
<abbrev>tuple</abbrev>
<title>The Boost Tuple Library</title>
@@ -3435,7 +3400,7 @@ was dropped.
<firstname>Brian</firstname>
<surname>McNamara</surname>
</author>
<bibliomisc><ulink url="http://yanniss.github.io/fc++/">yanniss.github.io/fc++/ </ulink>
<bibliomisc><ulink url="http://www.cc.gatech.edu/~yannis/fc++/">www.cc.gatech.edu/~yannis/fc++/</ulink>
</bibliomisc>
<pubdate>2002</pubdate>
</biblioentry>
@@ -3447,7 +3412,7 @@ was dropped.
</library>
</article>

View File

@@ -1,12 +1,39 @@
<html>
<head>
<meta http-equiv="refresh" content="0; URL=../../../doc/html/lambda.html">
</head>
<body>
Automatic redirection failed, please go to <a href="../../../doc/html/lambda.html">www.boost.org/doc/html/lambda.html</a>&nbsp;<hr>
<p>© Copyright Beman Dawes, 2001</p>
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
</body>
</html>
<!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#id2790109">Installing the library</a></dt><dt>2.2. <a href="ar01s02.html#id2741935">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#id2741989">Motivation</a></dt><dt>3.2. <a href="ar01s03.html#id2742784">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#id2805476">Special lambda expressions</a></dt><dt>5.10. <a href="ar01s05.html#id2806049">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#id2807564">Performance</a></dt><dt>7.2. <a href="ar01s07.html#id2808056">About compiling</a></dt><dt>7.3. <a href="ar01s07.html#id2808118">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#id2808509">Boost Function</a></dt><dt>8.2. <a href="ar01s08.html#id2808613">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><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 &lt;&lt; _1 &lt;&lt; ' ');</pre>
The expression <tt>std::cout &lt;&lt; _1 &lt;&lt; ' '</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 &#8216;body&#8217; 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>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,16 @@
// -- bind.hpp -- Boost Lambda Library --------------------------------------
// Copyright (C) 1999-2001 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// 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

View File

@@ -1,11 +1,16 @@
// - casts.hpp -- BLambda Library -------------
//
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000 Gary Powell (gary.powell@sierra.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
@@ -14,17 +19,11 @@
#if !defined(BOOST_LAMBDA_CASTS_HPP)
#define BOOST_LAMBDA_CASTS_HPP
#include "boost/lambda/detail/suppress_unused.hpp"
#include "boost/lambda/core.hpp"
#include <typeinfo>
namespace boost {
namespace lambda {
template<class Act, class Args>
struct return_type_N;
template<class T> class cast_action;
template<class T> class static_cast_action;
@@ -70,12 +69,11 @@ public:
}
};
// typeid action
// typedid action
class typeid_action {
public:
template<class RET, class Arg1>
static RET apply(Arg1 &a1) {
detail::suppress_unused_variable_warnings(a1);
return typeid(a1);
}
};

View File

@@ -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/
@@ -251,7 +266,7 @@ private:
closure& operator=(closure const&); // no assign
template <int N, typename ClosureT>
friend class closure_member;
friend struct closure_member;
template <typename ClosureT>
friend class closure_frame;

View File

@@ -1,11 +1,16 @@
// - construct.hpp -- Lambda Library -------------
//
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000 Gary Powell (gary.powell@sierra.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
//
@@ -14,9 +19,6 @@
#if !defined(BOOST_LAMBDA_CONSTRUCT_HPP)
#define BOOST_LAMBDA_CONSTRUCT_HPP
#include "boost/type_traits/remove_cv.hpp"
#include "boost/type_traits/is_pointer.hpp"
namespace boost {
namespace lambda {

View File

@@ -1,9 +1,14 @@
// -- control_structures.hpp -- Boost Lambda Library --------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// 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
@@ -17,7 +22,6 @@
#include "boost/lambda/detail/operator_actions.hpp"
#include "boost/lambda/detail/operator_return_type_traits.hpp"
#include "boost/lambda/if.hpp"
#include "boost/lambda/loops.hpp"
#include "boost/lambda/detail/control_structures_impl.hpp"
#endif

View File

@@ -1,13 +1,4 @@
// -- core.hpp -- Boost Lambda Library -------------------------------------
//
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
// Copyright (C) 1999, 2000 Jaakko Jarvi (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)
//
// For more information, see www.boost.org
//
// Includes the core of LL, without any real features for client:
//
@@ -22,8 +13,6 @@
#ifndef BOOST_LAMBDA_CORE_HPP
#define BOOST_LAMBDA_CORE_HPP
#include "boost/config.hpp"
#include "boost/type_traits/transform_traits.hpp"
#include "boost/type_traits/cv_traits.hpp"
@@ -68,9 +57,9 @@ namespace {
boost::lambda::placeholder2_type free2 = boost::lambda::placeholder2_type();
boost::lambda::placeholder3_type free3 = boost::lambda::placeholder3_type();
boost::lambda::placeholder1_type& BOOST_ATTRIBUTE_UNUSED _1 = free1;
boost::lambda::placeholder2_type& BOOST_ATTRIBUTE_UNUSED _2 = free2;
boost::lambda::placeholder3_type& BOOST_ATTRIBUTE_UNUSED _3 = free3;
boost::lambda::placeholder1_type& _1 = free1;
boost::lambda::placeholder2_type& _2 = free2;
boost::lambda::placeholder3_type& _3 = free3;
// _1, _2, ... naming scheme by Peter Dimov
} // unnamed

View File

@@ -1,10 +1,15 @@
// -- Boost Lambda Library - actions.hpp ----------------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// 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

View File

@@ -1,10 +1,15 @@
// -- Boost Lambda Library -------------------------------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// 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

View File

@@ -1,10 +1,15 @@
// -- bind_functions.hpp -- Boost Lambda Library
//
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// 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,

View File

@@ -1,11 +1,16 @@
// Boost Lambda Library -- control_constructs_common.hpp -------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
// 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 to its suitability for any purpose.
//
// For more information, see www.boost.org

View File

@@ -0,0 +1,555 @@
// Boost Lambda Library -- control_structures_impl.hpp ---------------------
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000 Gary Powell (gary.powell@sierra.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
// --------------------------------------------------------------------------
#if !defined(BOOST_LAMBDA_CONTROL_CONSTRUCTS_HPP)
#define BOOST_LAMBDA_CONTROL_CONSTRUCTS_HPP
namespace boost {
namespace lambda {
// -- void return control actions ----------------------
class forloop_action {};
class forloop_no_body_action {};
class ifthen_action {};
class ifthenelse_action {};
class whileloop_action {};
class whileloop_no_body_action {};
class dowhileloop_action {};
class dowhileloop_no_body_action {};
// -- nonvoid return control actions ----------------------
class ifthenelsereturn_action {};
// For loop
template <class Arg1, class Arg2, class Arg3, class Arg4>
inline const
lambda_functor<
lambda_functor_base<
forloop_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
lambda_functor<Arg3>, lambda_functor<Arg4> >
>
>
for_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2,
const lambda_functor<Arg3>& a3, const lambda_functor<Arg4>& a4) {
return
lambda_functor_base<
forloop_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
lambda_functor<Arg3>, lambda_functor<Arg4> >
>
( tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
lambda_functor<Arg3>, lambda_functor<Arg4> >(a1, a2, a3, a4)
);
}
// No body case.
template <class Arg1, class Arg2, class Arg3>
inline const
lambda_functor<
lambda_functor_base<
forloop_no_body_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
>
>
for_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2,
const lambda_functor<Arg3>& a3) {
return
lambda_functor_base<
forloop_no_body_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
lambda_functor<Arg3> >
>
( tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
lambda_functor<Arg3> >(a1, a2, a3) );
}
// While loop
template <class Arg1, class Arg2>
inline const
lambda_functor<
lambda_functor_base<
whileloop_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
>
>
while_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2) {
return
lambda_functor_base<
whileloop_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
>
( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2));
}
// No body case.
template <class Arg1>
inline const
lambda_functor<
lambda_functor_base<
whileloop_no_body_action,
tuple<lambda_functor<Arg1> >
>
>
while_loop(const lambda_functor<Arg1>& a1) {
return
lambda_functor_base<
whileloop_no_body_action,
tuple<lambda_functor<Arg1> >
>
( tuple<lambda_functor<Arg1> >(a1) );
}
// Do While loop
template <class Arg1, class Arg2>
inline const
lambda_functor<
lambda_functor_base<
dowhileloop_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
>
>
do_while_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2) {
return
lambda_functor_base<
dowhileloop_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
>
( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2));
}
// No body case.
template <class Arg1>
inline const
lambda_functor<
lambda_functor_base<
dowhileloop_no_body_action,
tuple<lambda_functor<Arg1> >
>
>
do_while_loop(const lambda_functor<Arg1>& a1) {
return
lambda_functor_base<
dowhileloop_no_body_action,
tuple<lambda_functor<Arg1> >
>
( tuple<lambda_functor<Arg1> >(a1));
}
// If Then
template <class Arg1, class Arg2>
inline const
lambda_functor<
lambda_functor_base<
ifthen_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
>
>
if_then(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2) {
return
lambda_functor_base<
ifthen_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
>
( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2) );
}
// If then else
template <class Arg1, class Arg2, class Arg3>
inline const
lambda_functor<
lambda_functor_base<
ifthenelse_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
>
>
if_then_else(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2,
const lambda_functor<Arg3>& a3) {
return
lambda_functor_base<
ifthenelse_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
>
(tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
(a1, a2, a3) );
}
// Our version of operator?:()
template <class Arg1, class Arg2, class Arg3>
inline const
lambda_functor<
lambda_functor_base<
other_action<ifthenelsereturn_action>,
tuple<lambda_functor<Arg1>,
typename const_copy_argument<Arg2>::type,
typename const_copy_argument<Arg3>::type>
>
>
if_then_else_return(const lambda_functor<Arg1>& a1,
const Arg2 & a2,
const Arg3 & a3) {
return
lambda_functor_base<
other_action<ifthenelsereturn_action>,
tuple<lambda_functor<Arg1>,
typename const_copy_argument<Arg2>::type,
typename const_copy_argument<Arg3>::type>
> ( tuple<lambda_functor<Arg1>,
typename const_copy_argument<Arg2>::type,
typename const_copy_argument<Arg3>::type> (a1, a2, a3) );
}
namespace detail {
// return type specialization for conditional expression begins -----------
// start reading below and move upwards
// PHASE 6:1
// check if A is conbertible to B and B to A
template<int Phase, bool AtoB, bool BtoA, bool SameType, class A, class B>
struct return_type_2_ifthenelsereturn;
// if A can be converted to B and vice versa -> ambiguous
template<int Phase, class A, class B>
struct return_type_2_ifthenelsereturn<Phase, true, true, false, A, B> {
typedef
detail::return_type_deduction_failure<return_type_2_ifthenelsereturn> type;
// ambiguous type in conditional expression
};
// if A can be converted to B and vice versa and are of same type
template<int Phase, class A, class B>
struct return_type_2_ifthenelsereturn<Phase, true, true, true, A, B> {
typedef A type;
};
// A can be converted to B
template<int Phase, class A, class B>
struct return_type_2_ifthenelsereturn<Phase, true, false, false, A, B> {
typedef B type;
};
// B can be converted to A
template<int Phase, class A, class B>
struct return_type_2_ifthenelsereturn<Phase, false, true, false, A, B> {
typedef A type;
};
// neither can be converted. Then we drop the potential references, and
// try again
template<class A, class B>
struct return_type_2_ifthenelsereturn<1, false, false, false, A, B> {
// it is safe to add const, since the result will be an rvalue and thus
// const anyway. The const are needed eg. if the types
// are 'const int*' and 'void *'. The remaining type should be 'const void*'
typedef const typename boost::remove_reference<A>::type plainA;
typedef const typename boost::remove_reference<B>::type plainB;
// TODO: Add support for volatile ?
typedef typename
return_type_2_ifthenelsereturn<
2,
boost::is_convertible<plainA,plainB>::value,
boost::is_convertible<plainB,plainA>::value,
boost::is_same<plainA,plainB>::value,
plainA,
plainB>::type type;
};
// PHASE 6:2
template<class A, class B>
struct return_type_2_ifthenelsereturn<2, false, false, false, A, B> {
typedef
detail::return_type_deduction_failure<return_type_2_ifthenelsereturn> type;
// types_do_not_match_in_conditional_expression
};
// PHASE 5: now we know that types are not arithmetic.
template<class A, class B>
struct non_numeric_types {
typedef typename
return_type_2_ifthenelsereturn<
1, // phase 1
is_convertible<A,B>::value,
is_convertible<B,A>::value,
is_same<A,B>::value,
A,
B>::type type;
};
// PHASE 4 :
// the base case covers arithmetic types with differing promote codes
// use the type deduction of arithmetic_actions
template<int CodeA, int CodeB, class A, class B>
struct arithmetic_or_not {
typedef typename
return_type_2<arithmetic_action<plus_action>, A, B>::type type;
// plus_action is just a random pick, has to be a concrete instance
};
// this case covers the case of artihmetic types with the same promote codes.
// non numeric deduction is used since e.g. integral promotion is not
// performed with operator ?:
template<int CodeA, class A, class B>
struct arithmetic_or_not<CodeA, CodeA, A, B> {
typedef typename non_numeric_types<A, B>::type type;
};
// if either A or B has promote code -1 it is not an arithmetic type
template<class A, class B>
struct arithmetic_or_not <-1, -1, A, B> {
typedef typename non_numeric_types<A, B>::type type;
};
template<int CodeB, class A, class B>
struct arithmetic_or_not <-1, CodeB, A, B> {
typedef typename non_numeric_types<A, B>::type type;
};
template<int CodeA, class A, class B>
struct arithmetic_or_not <CodeA, -1, A, B> {
typedef typename non_numeric_types<A, B>::type type;
};
// PHASE 3 : Are the types same?
// No, check if they are arithmetic or not
template <class A, class B>
struct same_or_not {
typedef typename detail::remove_reference_and_cv<A>::type plainA;
typedef typename detail::remove_reference_and_cv<B>::type plainB;
typedef typename
arithmetic_or_not<
detail::promote_code<plainA>::value,
detail::promote_code<plainB>::value,
A,
B>::type type;
};
// Yes, clear.
template <class A> struct same_or_not<A, A> {
typedef A type;
};
} // detail
// PHASE 2 : Perform first the potential array_to_pointer conversion
template<class A, class B>
struct return_type_2<other_action<ifthenelsereturn_action>, A, B> {
typedef typename detail::array_to_pointer<A>::type A1;
typedef typename detail::array_to_pointer<B>::type B1;
typedef typename
boost::add_const<typename detail::same_or_not<A1, B1>::type>::type type;
};
// PHASE 1 : Deduction is based on the second and third operand
// return type specialization for conditional expression ends -----------
// Control loop lambda_functor_base specializations.
// Specialization for for_loop.
template<class Args>
class
lambda_functor_base<forloop_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
for(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS);
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS))
detail::select(boost::tuples::get<3>(args), CALL_ACTUAL_ARGS);
}
};
// No body case
template<class Args>
class
lambda_functor_base<forloop_no_body_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
for(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS);
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS)) {}
}
};
// Specialization for while_loop.
template<class Args>
class
lambda_functor_base<whileloop_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
while(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS))
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
}
};
// No body case
template<class Args>
class
lambda_functor_base<whileloop_no_body_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
while(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) {}
}
};
// Specialization for do_while_loop.
// Note that the first argument is the condition.
template<class Args>
class
lambda_functor_base<dowhileloop_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
do {
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
} while (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) );
}
};
// No body case
template<class Args>
class
lambda_functor_base<dowhileloop_no_body_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
do {} while (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) );
}
};
// Specialization for if_then.
template<class Args>
class
lambda_functor_base<ifthen_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
if (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
}
};
// Specialization for if_then_else.
template<class Args>
class
lambda_functor_base<ifthenelse_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
if (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS))
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
else
detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS);
}
};
// Specialization of lambda_functor_base for if_then_else_return.
template<class Args>
class
lambda_functor_base<other_action<ifthenelsereturn_action>, Args> {
public:
Args args;
template <class SigArgs> struct sig {
private:
typedef typename detail::nth_return_type_sig<1, Args, SigArgs>::type ret1;
typedef typename detail::nth_return_type_sig<2, Args, SigArgs>::type ret2;
public:
typedef typename return_type_2<
other_action<ifthenelsereturn_action>, ret1, ret2
>::type type;
};
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
return (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) ?
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS)
:
detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS);
}
};
} // lambda
} // boost
#endif // BOOST_LAMBDA_CONTROL_CONSTRUCTS_HPP

View File

@@ -1,10 +1,15 @@
// Boost Lambda Library - function_adaptors.hpp ----------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// 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,170 +17,25 @@
#ifndef BOOST_LAMBDA_FUNCTION_ADAPTORS_HPP
#define BOOST_LAMBDA_FUNCTION_ADAPTORS_HPP
#include "boost/mpl/has_xxx.hpp"
#include "boost/tuple/tuple.hpp"
#include "boost/type_traits/same_traits.hpp"
#include "boost/type_traits/remove_reference.hpp"
#include "boost/type_traits/remove_cv.hpp"
#include "boost/type_traits/add_const.hpp"
#include "boost/type_traits/add_volatile.hpp"
#include "boost/utility/result_of.hpp"
namespace boost {
namespace lambda {
namespace detail {
BOOST_MPL_HAS_XXX_TEMPLATE_DEF(sig)
template<class Tuple>
struct remove_references_from_elements {
typedef typename boost::tuples::cons<
typename boost::remove_reference<typename Tuple::head_type>::type,
typename remove_references_from_elements<typename Tuple::tail_type>::type
> type;
};
template<>
struct remove_references_from_elements<boost::tuples::null_type> {
typedef boost::tuples::null_type type;
};
}
template <class Func> struct function_adaptor {
typedef typename detail::remove_reference_and_cv<Func>::type plainF;
#if !defined(BOOST_NO_RESULT_OF)
// Support functors that use the boost::result_of return type convention.
template<class Tuple, int Length, bool HasSig>
struct result_converter;
template<class Tuple, int Length>
struct result_converter<Tuple, Length, true>
: plainF::template sig<
typename detail::remove_references_from_elements<Tuple>::type
>
{};
template<class Tuple>
struct result_converter<Tuple, 0, false>
: result_of<plainF()>
{};
template<class Tuple>
struct result_converter<Tuple, 1, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 2, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 3, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type,
typename tuples::element<3, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 4, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type,
typename tuples::element<3, Tuple>::type,
typename tuples::element<4, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 5, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type,
typename tuples::element<3, Tuple>::type,
typename tuples::element<4, Tuple>::type,
typename tuples::element<5, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 6, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type,
typename tuples::element<3, Tuple>::type,
typename tuples::element<4, Tuple>::type,
typename tuples::element<5, Tuple>::type,
typename tuples::element<6, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 7, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type,
typename tuples::element<3, Tuple>::type,
typename tuples::element<4, Tuple>::type,
typename tuples::element<5, Tuple>::type,
typename tuples::element<6, Tuple>::type,
typename tuples::element<7, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 8, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type,
typename tuples::element<3, Tuple>::type,
typename tuples::element<4, Tuple>::type,
typename tuples::element<5, Tuple>::type,
typename tuples::element<6, Tuple>::type,
typename tuples::element<7, Tuple>::type,
typename tuples::element<8, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 9, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type,
typename tuples::element<3, Tuple>::type,
typename tuples::element<4, Tuple>::type,
typename tuples::element<5, Tuple>::type,
typename tuples::element<6, Tuple>::type,
typename tuples::element<7, Tuple>::type,
typename tuples::element<8, Tuple>::type,
typename tuples::element<9, Tuple>::type)
>
{};
// we do not know the return type off-hand, we must ask it from Func
// To sig we pass a cons list, where the head is the function object type
// itself (potentially cv-qualified)
// and the tail contains the types of the actual arguments to be passed
// to the function object. The arguments can be cv qualified
// as well.
template <class Args>
struct sig
: result_converter<
Args
, tuples::length<typename Args::tail_type>::value
, detail::has_sig<plainF>::value
>
{};
#else // BOOST_NO_RESULT_OF
template <class Args> class sig {
template <class Args> class sig {
typedef typename Args::head_type F;
typedef typename detail::remove_reference_and_cv<Func>::type plainF;
public:
typedef typename plainF::template sig<
typename detail::remove_references_from_elements<Args>::type
>::type type;
// To sig we pass a cons list, where the head is the function object type
// itself (potentially cv-qualified)
// and the tail contains the types of the actual arguments to be passed
// to the function object. The arguments can be cv qualified
// as well.
typedef typename plainF::template sig<Args>::type type;
};
#endif
template<class RET, class A1>
static RET apply(A1& a1) {
@@ -240,26 +100,22 @@ struct function_adaptor<T Object::*> {
// the data member is accessed is const, and finally adding a reference
template<class Args> class sig {
typedef typename boost::tuples::element<1, Args>::type argument_type;
typedef typename boost::remove_reference<
argument_type
>::type unref_type;
typedef typename detail::IF<boost::is_const<unref_type>::value,
typedef typename detail::IF<boost::is_const<argument_type>::value,
typename boost::add_const<T>::type,
T
>::RET properly_consted_return_type;
typedef typename detail::IF<boost::is_volatile<unref_type>::value,
typedef typename detail::IF<
boost::is_volatile<properly_consted_return_type>::value,
typename boost::add_volatile<properly_consted_return_type>::type,
properly_consted_return_type
>::RET properly_cvd_return_type;
public:
typedef typename detail::IF<boost::is_reference<argument_type>::value,
typename boost::add_reference<properly_cvd_return_type>::type,
typename boost::remove_cv<T>::type
>::RET type;
typedef typename
boost::add_reference<properly_cvd_return_type>::type type;
};
template <class RET>
@@ -489,7 +345,6 @@ struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3) const> {
template <class Object, class Arg1, class Arg2, class Arg3, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3), Object* o, A1& a1, A2& a2, A3& a3) {
return (o->*func)(a1, a2, a3);

View File

@@ -1,10 +1,15 @@
// Boost Lambda Library - is_instance_of.hpp ---------------------
// Copyright (C) 2001 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// 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

View File

@@ -1,10 +1,15 @@
// Boost Lambda Library - lambda_config.hpp ------------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// 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,11 +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
# endif // __GNUC__
# if (__GNUC__ == 2 && __GNUC_MINOR__ <= 97)
#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__
#if defined __KCC

View File

@@ -1,10 +1,15 @@
// Boost Lambda Library lambda_functor_base.hpp -----------------------------
//
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// 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
@@ -13,19 +18,9 @@
#ifndef BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_HPP
#define BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_HPP
#include "boost/type_traits/add_reference.hpp"
#include "boost/type_traits/add_const.hpp"
#include "boost/type_traits/remove_const.hpp"
#include "boost/lambda/detail/lambda_fwd.hpp"
#include "boost/lambda/detail/lambda_traits.hpp"
namespace boost {
namespace lambda {
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(push)
#pragma warning(disable:4512) //assignment operator could not be generated
#endif
// for return type deductions we wrap bound argument to this class,
// which fulfils the base class contract for lambda_functors
@@ -37,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
@@ -46,16 +41,12 @@ public:
explicit identity(par_t t) : elem(t) {}
template <typename SigArgs>
struct sig { typedef typename boost::remove_const<element_t>::type type; };
struct sig { typedef element_t type; };
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return elem; }
};
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(pop)
#endif
template <class T>
inline lambda_functor<identity<T&> > var(T& t) { return identity<T&>(t); }
@@ -276,8 +267,6 @@ class lambda_functor_base<explicit_return_type_action<RET>, Args>
public:
Args args;
typedef RET result_type;
explicit lambda_functor_base(const Args& a) : args(a) {}
template <class SigArgs> struct sig { typedef RET type; };
@@ -326,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
@@ -353,7 +342,7 @@ class lambda_functor_base<action<0, Act>, Args>
{
public:
// Args args; not needed
explicit lambda_functor_base(const Args& /*a*/) {}
explicit lambda_functor_base(const Args& a) {}
template<class SigArgs> struct sig {
typedef typename return_type_N<Act, null_type>::type type;
@@ -383,7 +372,7 @@ public: \
\
template<class SigArgs> struct sig { \
typedef typename \
detail::deduce_argument_types<Args, SigArgs>::type rets_t; \
detail::deduce_non_ref_argument_types<Args, SigArgs>::type rets_t; \
public: \
typedef typename \
return_type_N_prot<Act, rets_t>::type type; \

View File

@@ -1,10 +1,15 @@
// Boost Lambda Library - lambda_functors.hpp -------------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// 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
@@ -13,31 +18,6 @@
#ifndef BOOST_LAMBDA_LAMBDA_FUNCTORS_HPP
#define BOOST_LAMBDA_LAMBDA_FUNCTORS_HPP
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/utility/result_of.hpp>
#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
#include <boost/mpl/or.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_array.hpp>
#define BOOST_LAMBDA_DISABLE_IF_ARRAY1(A1, R1)\
typename lazy_disable_if<is_array<A1>, typename R1 >::type
#define BOOST_LAMBDA_DISABLE_IF_ARRAY2(A1, A2, R1, R2) \
typename lazy_disable_if<mpl::or_<is_array<A1>, is_array<A2> >, typename R1, R2 >::type
#define BOOST_LAMBDA_DISABLE_IF_ARRAY3(A1, A2, A3, R1, R2, R3) \
typename lazy_disable_if<mpl::or_<is_array<A1>, is_array<A2>, is_array<A3> >, typename R1, R2, R3 >::type
#else
#define BOOST_LAMBDA_DISABLE_IF_ARRAY1(A1, R1) typename R1::type
#define BOOST_LAMBDA_DISABLE_IF_ARRAY2(A1, A2, R1, R2) typename R1, R2::type
#define BOOST_LAMBDA_DISABLE_IF_ARRAY3(A1, A2, A3, R1, R2, R3) typename R1, R2, R3::type
#endif
namespace boost {
namespace lambda {
@@ -130,10 +110,7 @@ typedef const lambda_functor<placeholder<THIRD> > placeholder3_type;
// other lambda_functors.
// -------------------------------------------------------------------
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(push)
#pragma warning(disable:4512) //assignment operator could not be generated
#endif
// -- lambda_functor NONE ------------------------------------------------
template <class T>
@@ -162,25 +139,6 @@ public:
inherited::template sig<null_type>::type
nullary_return_type;
// Support for boost::result_of.
template <class Sig> struct result;
template <class F>
struct result<F()> {
typedef nullary_return_type type;
};
template <class F, class A>
struct result<F(A)> {
typedef typename sig<tuple<F, A> >::type type;
};
template <class F, class A, class B>
struct result<F(A, B)> {
typedef typename sig<tuple<F, A, B> >::type type;
};
template <class F, class A, class B, class C>
struct result<F(A, B, C)> {
typedef typename sig<tuple<F, A, B, C> >::type type;
};
nullary_return_type operator()() const {
return inherited::template
call<nullary_return_type>
@@ -195,14 +153,6 @@ public:
>(a, cnull_type(), cnull_type(), cnull_type());
}
template<class A>
BOOST_LAMBDA_DISABLE_IF_ARRAY1(A, inherited::template sig<tuple<A const&> >)
operator()(A const& a) const {
return inherited::template call<
typename inherited::template sig<tuple<A const&> >::type
>(a, cnull_type(), cnull_type(), cnull_type());
}
template<class A, class B>
typename inherited::template sig<tuple<A&, B&> >::type
operator()(A& a, B& b) const {
@@ -211,30 +161,6 @@ public:
>(a, b, cnull_type(), cnull_type());
}
template<class A, class B>
BOOST_LAMBDA_DISABLE_IF_ARRAY2(A, B, inherited::template sig<tuple<A const&, B&> >)
operator()(A const& a, B& b) const {
return inherited::template call<
typename inherited::template sig<tuple<A const&, B&> >::type
>(a, b, cnull_type(), cnull_type());
}
template<class A, class B>
BOOST_LAMBDA_DISABLE_IF_ARRAY2(A, B, inherited::template sig<tuple<A&, B const&> >)
operator()(A& a, B const& b) const {
return inherited::template call<
typename inherited::template sig<tuple<A&, B const&> >::type
>(a, b, cnull_type(), cnull_type());
}
template<class A, class B>
BOOST_LAMBDA_DISABLE_IF_ARRAY2(A, B, inherited::template sig<tuple<A const&, B const&> >)
operator()(A const& a, B const& b) const {
return inherited::template call<
typename inherited::template sig<tuple<A const&, B const&> >::type
>(a, b, cnull_type(), cnull_type());
}
template<class A, class B, class C>
typename inherited::template sig<tuple<A&, B&, C&> >::type
operator()(A& a, B& b, C& c) const
@@ -244,15 +170,6 @@ public:
>(a, b, c, cnull_type());
}
template<class A, class B, class C>
BOOST_LAMBDA_DISABLE_IF_ARRAY3(A, B, C, inherited::template sig<tuple<A const&, B const&, C const&> >)
operator()(A const& a, B const& b, C const& c) const
{
return inherited::template call<
typename inherited::template sig<tuple<A const&, B const&, C const&> >::type
>(a, b, c, cnull_type());
}
// for internal calls with env
template<CALL_TEMPLATE_ARGS>
typename inherited::template sig<tuple<CALL_REFERENCE_TYPES> >::type
@@ -291,67 +208,10 @@ public:
}
};
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(pop)
#endif
} // namespace lambda
} // namespace boost
namespace boost {
#if !defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_NO_CXX11_DECLTYPE)
template<class T>
struct result_of<boost::lambda::lambda_functor<T>()>
{
typedef typename boost::lambda::lambda_functor<T>::nullary_return_type type;
};
template<class T>
struct result_of<const boost::lambda::lambda_functor<T>()>
{
typedef typename boost::lambda::lambda_functor<T>::nullary_return_type type;
};
#endif
template<class T>
struct tr1_result_of<boost::lambda::lambda_functor<T>()>
{
typedef typename boost::lambda::lambda_functor<T>::nullary_return_type type;
};
template<class T>
struct tr1_result_of<const boost::lambda::lambda_functor<T>()>
{
typedef typename boost::lambda::lambda_functor<T>::nullary_return_type type;
};
}
// is_placeholder
#include <boost/is_placeholder.hpp>
namespace boost
{
template<> struct is_placeholder< lambda::lambda_functor< lambda::placeholder<lambda::FIRST> > >
{
enum _vt { value = 1 };
};
template<> struct is_placeholder< lambda::lambda_functor< lambda::placeholder<lambda::SECOND> > >
{
enum _vt { value = 2 };
};
template<> struct is_placeholder< lambda::lambda_functor< lambda::placeholder<lambda::THIRD> > >
{
enum _vt { value = 3 };
};
} // namespace boost
#endif

View File

@@ -1,10 +1,15 @@
// lambda_fwd.hpp - Boost Lambda Library -------------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// 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)

View File

@@ -1,10 +1,15 @@
// - lambda_traits.hpp --- Boost Lambda Library ----------------------------
//
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// 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
// -------------------------------------------------------------------------
@@ -16,7 +21,6 @@
#include "boost/type_traits/cv_traits.hpp"
#include "boost/type_traits/function_traits.hpp"
#include "boost/type_traits/object_traits.hpp"
#include "boost/tuple/tuple.hpp"
namespace boost {
namespace lambda {
@@ -282,11 +286,6 @@ struct const_copy_argument<void> {
typedef void type;
};
template<>
struct const_copy_argument<void const> {
typedef void type;
};
// Does the same as const_copy_argument, but passes references through as such
template<class T>
@@ -436,56 +435,6 @@ struct bind_traits<const volatile T[n]> {
typedef const volatile T (&type)[n];
};
template<class R>
struct bind_traits<R()> {
typedef R(&type)();
};
template<class R, class Arg1>
struct bind_traits<R(Arg1)> {
typedef R(&type)(Arg1);
};
template<class R, class Arg1, class Arg2>
struct bind_traits<R(Arg1, Arg2)> {
typedef R(&type)(Arg1, Arg2);
};
template<class R, class Arg1, class Arg2, class Arg3>
struct bind_traits<R(Arg1, Arg2, Arg3)> {
typedef R(&type)(Arg1, Arg2, Arg3);
};
template<class R, class Arg1, class Arg2, class Arg3, class Arg4>
struct bind_traits<R(Arg1, Arg2, Arg3, Arg4)> {
typedef R(&type)(Arg1, Arg2, Arg3, Arg4);
};
template<class R, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
struct bind_traits<R(Arg1, Arg2, Arg3, Arg4, Arg5)> {
typedef R(&type)(Arg1, Arg2, Arg3, Arg4, Arg5);
};
template<class R, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6>
struct bind_traits<R(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)> {
typedef R(&type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6);
};
template<class R, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7>
struct bind_traits<R(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)> {
typedef R(&type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7);
};
template<class R, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8>
struct bind_traits<R(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8)> {
typedef R(&type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8);
};
template<class R, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8, class Arg9>
struct bind_traits<R(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9)> {
typedef R(&type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9);
};
template<class T>
struct bind_traits<reference_wrapper<T> >{
typedef T& type;

View File

@@ -1,11 +1,16 @@
// Boost Lambda Library -- member_ptr.hpp ---------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// 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
@@ -619,7 +624,7 @@ public:
detail::member_pointer<plainB>::is_data_member,
boost::is_pointer<A>::value &&
detail::member_pointer<plainB>::is_function_member
>::template apply<RET>(a, b);
>::template apply<RET>(a, b);
}
};

View File

@@ -1,10 +1,15 @@
// -- operator_actions.hpp - Boost Lambda Library ----------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// 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

View File

@@ -1,10 +1,15 @@
// Boost Lambda Library - operator_lambda_func_base.hpp -----------------
//
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// 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

View File

@@ -1,10 +1,15 @@
// operator_return_type_traits.hpp -- Boost Lambda Library ------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// 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,16 +17,7 @@
#define BOOST_LAMBDA_OPERATOR_RETURN_TYPE_TRAITS_HPP
#include "boost/lambda/detail/is_instance_of.hpp"
#include "boost/type_traits/is_same.hpp"
#include "boost/type_traits/is_pointer.hpp"
#include "boost/type_traits/is_float.hpp"
#include "boost/type_traits/is_convertible.hpp"
#include "boost/type_traits/remove_pointer.hpp"
#include "boost/type_traits/remove_const.hpp"
#include "boost/type_traits/remove_reference.hpp"
#include "boost/indirect_reference.hpp"
#include "boost/detail/container_fwd.hpp"
#include "boost/type_traits/same_traits.hpp"
#include <cstddef> // needed for the ptrdiff_t
#include <iosfwd> // for istream and ostream
@@ -65,6 +61,10 @@ template <> struct promote_code<long double> { static const int value = 700; };
} // namespace lambda
} // namespace boost
namespace std {
template<class T> class complex;
}
namespace boost {
namespace lambda {
namespace detail {
@@ -221,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
@@ -231,15 +231,34 @@ template <> struct contentsof_type<null_type> {
template <class A> struct contentsof_type<const A> {
typedef typename contentsof_type<A>::type type;
typedef typename contentsof_type<A>::type type1;
// return a reference to the underlying const type
// the IF is because the A::reference in the primary template could
// be some class type rather than a real reference, hence
// we do not want to make it a reference here either
typedef typename detail::IF<
is_reference<type1>::value,
const typename boost::remove_reference<type1>::type &,
const type1
>::RET type;
};
template <class A> struct contentsof_type<volatile A> {
typedef typename contentsof_type<A>::type type;
typedef typename contentsof_type<A>::type type1;
typedef typename detail::IF<
is_reference<type1>::value,
volatile typename boost::remove_reference<type1>::type &,
volatile type1
>::RET type;
};
template <class A> struct contentsof_type<const volatile A> {
typedef typename contentsof_type<A>::type type;
typedef typename contentsof_type<A>::type type1;
typedef typename detail::IF<
is_reference<type1>::value,
const volatile typename boost::remove_reference<type1>::type &,
const volatile type1
>::RET type;
};
// standard iterator traits should take care of the pointer types
@@ -473,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;
};
@@ -542,6 +562,36 @@ struct return_type_2<bitwise_action<Act>, A, B>
namespace detail {
#ifdef BOOST_NO_TEMPLATED_STREAMS
template<class A, class B>
struct leftshift_type {
typedef typename detail::IF<
boost::is_convertible<
typename boost::remove_reference<A>::type*,
std::ostream*
>::value,
std::ostream&,
typename detail::remove_reference_and_cv<A>::type
>::RET type;
};
template<class A, class B>
struct rightshift_type {
typedef typename detail::IF<
boost::is_convertible<
typename boost::remove_reference<A>::type*,
std::istream*
>::value,
std::istream&,
typename detail::remove_reference_and_cv<A>::type
>::RET type;
};
#else
template <class T> struct get_ostream_type {
typedef std::basic_ostream<typename T::char_type,
@@ -578,6 +628,7 @@ public:
};
#endif
} // end detail
@@ -806,6 +857,23 @@ struct return_type_2<other_action<subscript_action>, A, B> {
};
} // namespace lambda
} // namespace boost
namespace std {
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;
}
namespace boost {
namespace lambda {
template<class Key, class T, class Cmp, class Allocator, class B>
struct plain_return_type_2<other_action<subscript_action>, std::map<Key, T, Cmp, Allocator>, B> {
typedef T& type;
@@ -848,41 +916,6 @@ struct plain_return_type_2<other_action<subscript_action>, const std::basic_stri
typedef typename std::basic_string<Char, Traits, Allocator>::const_reference type;
};
template<class Char, class Traits, class Allocator>
struct plain_return_type_2<arithmetic_action<plus_action>,
std::basic_string<Char, Traits, Allocator>,
std::basic_string<Char, Traits, Allocator> > {
typedef std::basic_string<Char, Traits, Allocator> type;
};
template<class Char, class Traits, class Allocator>
struct plain_return_type_2<arithmetic_action<plus_action>,
const Char*,
std::basic_string<Char, Traits, Allocator> > {
typedef std::basic_string<Char, Traits, Allocator> type;
};
template<class Char, class Traits, class Allocator>
struct plain_return_type_2<arithmetic_action<plus_action>,
std::basic_string<Char, Traits, Allocator>,
const Char*> {
typedef std::basic_string<Char, Traits, Allocator> type;
};
template<class Char, class Traits, class Allocator, std::size_t N>
struct plain_return_type_2<arithmetic_action<plus_action>,
Char[N],
std::basic_string<Char, Traits, Allocator> > {
typedef std::basic_string<Char, Traits, Allocator> type;
};
template<class Char, class Traits, class Allocator, std::size_t N>
struct plain_return_type_2<arithmetic_action<plus_action>,
std::basic_string<Char, Traits, Allocator>,
Char[N]> {
typedef std::basic_string<Char, Traits, Allocator> type;
};
} // namespace lambda
} // namespace boost

View File

@@ -1,10 +1,15 @@
// Boost Lambda Library - operators.hpp --------------------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// 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 const_copy_argument <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 const_copy_argument <CONSTB>::type>\
tuple<lambda_functor<Arg>, typename CONVERSION <CONSTB B>::type> \
> \
(tuple<lambda_functor<Arg>, typename const_copy_argument <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)
@@ -161,6 +156,23 @@ namespace detail {
// Note that the overloading is const vs. non-const first argument
#ifdef BOOST_NO_TEMPLATED_STREAMS
template<class T> struct convert_ostream_to_ref_others_to_c_plain_by_default {
typedef typename detail::IF<
boost::is_convertible<T*, std::ostream*>::value,
T&,
typename const_copy_argument <T>::type
>::RET type;
};
template<class T> struct convert_istream_to_ref_others_to_c_plain_by_default {
typedef typename detail::IF<
boost::is_convertible<T*, std::istream*>::value,
T&,
typename const_copy_argument <T>::type
>::RET type;
};
#else
template<class T> struct convert_ostream_to_ref_others_to_c_plain_by_default {
typedef typename detail::IF<
@@ -181,11 +193,12 @@ template<class T> struct convert_istream_to_ref_others_to_c_plain_by_default {
typename const_copy_argument <T>::type
>::RET type;
};
#endif
} // 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.
@@ -240,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_base<ACTION, tuple<lambda_functor<Arg>, CONSTB(&)[N]> > \
(tuple<lambda_functor<Arg>, CONSTB(&)[N]>(a, b)); \
return lambda_functor< \
lambda_functor_base<ACTION, tuple<lambda_functor<Arg>, CONST B(&)[N]> > \
>(tuple<lambda_functor<Arg>, CONST B(&)[N]>(a, b)); \
}
@@ -258,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) \
template<int N, class A, class Arg> \
inline const \
lambda_functor< \
lambda_functor_base<ACTION, tuple<CONSTA(&)[N], lambda_functor<Arg> > > \
> \
OPER_NAME (CONSTA(&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)); \
#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<CONST A(&)[N], lambda_functor<Arg> > > \
> \
OPER_NAME (CONST A(&a)[N], const lambda_functor<Arg>& b) \
{ \
return \
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

View File

@@ -1,10 +1,15 @@
// Boost Lambda Library ret.hpp -----------------------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// 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> {
@@ -284,7 +289,7 @@ inline const
lambda_functor<
lambda_functor_base<do_nothing_action, null_type>
>
make_void(const Arg1&) {
make_void(const Arg1& a1) {
return
lambda_functor_base<do_nothing_action, null_type>();
}

View File

@@ -1,10 +1,15 @@
// return_type_traits.hpp -- Boost Lambda Library ---------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// 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,13 +17,15 @@
#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 {
namespace lambda {
using ::boost::type_traits::ice_and;
using ::boost::type_traits::ice_or;
using ::boost::type_traits::ice_not;
// Much of the type deduction code for standard arithmetic types
// from Gary Powell
@@ -73,7 +80,8 @@ template <class Act, class A> struct return_type_1_prot {
public:
typedef typename
detail::IF<
is_protectable<Act>::value && is_lambda_functor<A>::value,
// is_protectable<Act>::value && is_lambda_functor<A>::value,
ice_and<is_protectable<Act>::value, is_lambda_functor<A>::value>::value,
lambda_functor<
lambda_functor_base<
Act,
@@ -107,7 +115,9 @@ namespace detail {
// add const to rvalues, so that all rvalues are stored as const in
// the args tuple
typedef typename detail::IF_type<
boost::is_reference<T>::value && !boost::is_const<non_ref_T>::value,
// boost::is_reference<T>::value && !boost::is_const<non_ref_T>::value,
ice_and<boost::is_reference<T>::value,
ice_not<boost::is_const<non_ref_T>::value>::value>::value,
detail::identity_mapping<T>,
const_copy_argument<non_ref_T> // handles funtion and array
>::type type; // types correctly
@@ -141,8 +151,11 @@ template <class Act, class A, class B> struct return_type_2_prot {
typedef typename
detail::IF<
is_protectable<Act>::value &&
(is_lambda_functor<A>::value || is_lambda_functor<B>::value),
// is_protectable<Act>::value &&
// (is_lambda_functor<A>::value || is_lambda_functor<B>::value),
ice_and<is_protectable<Act>::value,
ice_or<is_lambda_functor<A>::value,
is_lambda_functor<B>::value>::value>::value,
lambda_functor<
lambda_functor_base<
Act,
@@ -177,8 +190,11 @@ struct return_type_2_comma
typedef typename
detail::IF<
is_protectable<other_action<comma_action> >::value && // it is protectable
(is_lambda_functor<A>::value || is_lambda_functor<B>::value),
// is_protectable<other_action<comma_action> >::value && // it is protectable
// (is_lambda_functor<A>::value || is_lambda_functor<B>::value),
ice_and<is_protectable<other_action<comma_action> >::value, // it is protectable
ice_or<is_lambda_functor<A>::value,
is_lambda_functor<B>::value>::value>::value,
lambda_functor<
lambda_functor_base<
other_action<comma_action>,
@@ -203,6 +219,8 @@ typedef typename
// currently there are no protectable actions with > 2 args
// Note, that if there will be, lambda_functor_base will have to be
// changed to not get rid of references in Args elements
template<class Act, class Args> struct return_type_N_prot {
typedef typename return_type_N<Act, Args>::type type;
@@ -221,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 > {
@@ -252,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;
};

View File

@@ -1,10 +1,15 @@
// -- select_functions.hpp -- Boost Lambda Library --------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// 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

View File

@@ -1,27 +0,0 @@
// Boost Lambda Library suppress_unused.hpp -----------------------------
//
// Copyright (C) 2009 Steven Watanabe
//
// 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)
//
// For more information, see www.boost.org
// ------------------------------------------------------------
#ifndef BOOST_LAMBDA_SUPPRESS_UNUSED_HPP
#define BOOST_LAMBDA_SUPPRESS_UNUSED_HPP
namespace boost {
namespace lambda {
namespace detail {
template<class T>
inline void suppress_unused_variable_warnings(const T&) {}
}
}
}
#endif

View File

@@ -1,11 +1,16 @@
// -- Boost Lambda Library -- exceptions.hpp ----------------
//
// Copyright (C) 2000 Gary Powell (gwpowell@hotmail.com)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// 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
@@ -14,7 +19,6 @@
#if !defined(BOOST_LAMBDA_EXCEPTIONS_HPP)
#define BOOST_LAMBDA_EXCEPTIONS_HPP
#include "boost/lambda/core.hpp"
#include "boost/lambda/detail/control_constructs_common.hpp"
namespace boost {
@@ -49,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> {

View File

@@ -1,12 +1,17 @@
// Boost Lambda Library -- if.hpp ------------------------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000 Gary Powell (gary.powell@sierra.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
@@ -345,7 +377,7 @@ public:
// is true, the true_statement (again an lambda_functor) is executed
// otherwise, the false_statement (another lambda_functor) is executed. The
// result type of this is void. Note the trailing underscore after
// if_ and the leading dot and the trailing underscore before
// if_ and the the leading dot and the trailing underscore before
// and after .else_.
//
///////////////////////////////////////////////////////////////////////////////

View File

@@ -1,9 +1,14 @@
// -- lambda.hpp -- Boost Lambda Library -----------------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// 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
@@ -24,6 +29,11 @@
#include "boost/lambda/detail/operators.hpp"
#ifndef BOOST_LAMBDA_FAILS_IN_TEMPLATE_KEYWORD_AFTER_SCOPE_OPER
// sorry, member ptr does not work with gcc2.95
#include "boost/lambda/detail/member_ptr.hpp"
#endif
#endif

View File

@@ -1,12 +1,16 @@
// Boost Lambda Library -- loops.hpp ----------------------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
// Copyright (c) 2001-2002 Joel de Guzman
// 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 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
@@ -348,7 +381,7 @@ while_(CondT const& cond)
// While the condition (an lambda_functor) evaluates to true, statement
// (another lambda_functor) is executed. The statement is executed at least
// once. The result type of this is void. Note the trailing
// underscore after do_ and the leading dot and the trailing
// underscore after do_ and the the leading dot and the trailing
// underscore before and after .while_.
//
///////////////////////////////////////////////////////////////////////////////

View File

@@ -1,10 +1,15 @@
// -- numeric.hpp -- Boost Lambda Library -----------------------------------
// Copyright (C) 2002 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// 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

View File

@@ -1,11 +1,16 @@
// Boost Lambda Library -- switch.hpp -----------------------------------
//
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000 Gary Powell (gary.powell@sierra.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
@@ -465,18 +470,12 @@ BOOST_LAMBDA_SWITCH( BOOST_PP_INC(N) )
#define BOOST_LAMBDA_SWITCH_STATEMENT_HELPER(z, N, A) \
BOOST_LAMBDA_SWITCH_STATEMENT(BOOST_PP_INC(N))
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4065)
#endif
// up to 9 cases supported (counting default:)
BOOST_PP_REPEAT_2ND(9,BOOST_LAMBDA_SWITCH_HELPER,FOO)
BOOST_PP_REPEAT_2ND(9,BOOST_LAMBDA_SWITCH_STATEMENT_HELPER,FOO)
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
} // namespace lambda
} // namespace boost

View File

@@ -1,12 +1,8 @@
<html>
<head>
<meta http-equiv="refresh" content="0; URL=../../doc/html/lambda.html">
<meta http-equiv="refresh" content="0; URL=doc/index.html">
</head>
<body>
Automatic redirection failed, please go to <a href="../../doc/html/lambda.html">www.boost.org/doc/html/lambda.html</a>&nbsp;<hr>
<p>© Copyright Beman Dawes, 2001</p>
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
Automatic redirection failed, please go to <a href="doc/index.html">doc/index.html</a>
</body>
</html>

View File

@@ -1,15 +0,0 @@
{
"key": "lambda",
"name": "Lambda",
"authors": [
"Jaakko Järvi",
"Gary Powell"
],
"description": "Define small unnamed function objects at the actual call site, and more.",
"category": [
"Function-objects"
],
"maintainers": [
"Jaakko Jarvi <jarvi -at- cs.tamu.edu>"
]
}

View File

@@ -1,35 +1,87 @@
# Lambda library
subproject libs/lambda/test ;
# Copyright (C) 2001-2003 Jaakko Järvi
unit-test is_instance_of_test
: is_instance_of_test.cpp
<lib>../../test/build/test_exec_monitor
: <sysinclude>$(BOOST_ROOT)
;
# Use, modification and distribution is subject to 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)
unit-test operator_tests_simple
: operator_tests_simple.cpp
<lib>../../test/build/test_exec_monitor
: <sysinclude>$(BOOST_ROOT)
;
# For more information, see http://www.boost.org/
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)
;
import testing ;
project
: requirements <toolset>msvc:<asynch-exceptions>on
;
test-suite lambda
: [ run algorithm_test.cpp ]
[ run bind_tests_simple.cpp ]
[ run bind_tests_advanced.cpp ]
[ run bind_tests_simple_f_refs.cpp ]
[ run bll_and_function.cpp ]
[ run cast_test.cpp : : : : lambda_cast_test ]
[ run constructor_tests.cpp ]
[ run control_structures.cpp ]
[ run exception_test.cpp ]
[ run extending_rt_traits.cpp ]
[ run is_instance_of_test.cpp ]
[ run member_pointer_test.cpp ]
[ run operator_tests_simple.cpp ]
[ run phoenix_control_structures.cpp ]
[ run switch_construct.cpp ]
[ run result_of_tests.cpp ]
[ run ret_test.cpp ]
;

4
test/Makefile Normal file → Executable file
View File

@@ -1,7 +1,7 @@
BOOST = ../../..
CXX = g++
EXTRAFLAGS = -pedantic -Wno-long-long -Wno-long-double -ftemplate-depth-50
CXX = gcc
EXTRAFLAGS = -pedantic -Wno-long-long -ftemplate-depth-50
LIBS = -lstdc++
#CXX = KCC

View File

@@ -1,60 +0,0 @@
// bll_and_function.cpp - The Boost Lambda Library -----------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 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)
//
// For more information, see www.boost.org
// test using BLL and boost::function
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/bind.hpp"
#include "boost/lambda/algorithm.hpp"
#include <vector>
#include <map>
#include <set>
#include <string>
#include <iostream>
void test_foreach() {
using namespace boost::lambda;
int a[10][20];
int sum = 0;
std::for_each(a, a + 10,
bind(ll::for_each(), _1, _1 + 20,
protect((_1 = var(sum), ++var(sum)))));
sum = 0;
std::for_each(a, a + 10,
bind(ll::for_each(), _1, _1 + 20,
protect((sum += _1))));
BOOST_CHECK(sum == (199 + 1)/ 2 * 199);
}
// More tests needed (for all algorithms)
int test_main(int, char *[]) {
test_foreach();
return 0;
}

View File

@@ -1,28 +1,13 @@
// bind_tests_advanced.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
// Copyright (C) 2010 Steven Watanabe
//
// 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)
//
// For more information, see www.boost.org
// bind_tests_advanced.cpp --------------------------------
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#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 "boost/type_traits/is_reference.hpp"
#include "boost/mpl/assert.hpp"
#include "boost/mpl/if.hpp"
#include <iostream>
@@ -31,8 +16,7 @@
#include <algorithm>
using namespace boost::lambda;
namespace bl = boost::lambda;
using namespace boost::lambda;
int sum_0() { return 0; }
int sum_1(int a) { return a; }
@@ -65,16 +49,16 @@ void test_nested_binds()
bool condition;
condition = true;
BOOST_CHECK(bind(bind(&sum_or_product, _1), 1, 2)(condition)==3);
BOOST_CHECK(bind(bind(&sum_or_product, _1), _2, _3)(condition, j, k)==5);
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_CHECK(bind(bind(&sum_or_product, _1), 1, 2)(condition)==2);
BOOST_CHECK(bind(bind(&sum_or_product, _1), _2, _3)(condition, j, k)==6);
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_CHECK(bind(bind(bind(wo), _1), _2, _3)(condition, j, k)==6);
BOOST_TEST(bind(bind(bind(wo), _1), _2, _3)(condition, j, k)==6);
return;
@@ -96,7 +80,7 @@ int call_with_100(const F& f) {
// This would result in;
// bind(_1 + 1, _1)(make_const(100)) , which would be a compile time error
return bl::bind(unlambda(f), _1)(make_const(100));
return bind(unlambda(f), _1)(make_const(100));
// for other functors than lambda functors, unlambda has no effect
// (except for making them const)
@@ -114,26 +98,18 @@ void test_unlambda() {
int i = 1;
BOOST_CHECK(unlambda(_1 + _2)(i, i) == 2);
BOOST_CHECK(unlambda(++var(i))() == 2);
BOOST_CHECK(call_with_100(_1 + 1) == 101);
BOOST_TEST(unlambda(_1 + _2)(i, i) == 2);
BOOST_TEST(unlambda(++var(i))() == 2);
BOOST_TEST(call_with_100(_1 + 1) == 101);
BOOST_CHECK(call_with_101(_1 + 1) == 102);
BOOST_TEST(call_with_101(_1 + 1) == 102);
#if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
BOOST_CHECK(call_with_100(bl::bind(std_functor(std::bind1st(std::plus<int>(), 1)), _1)) == 101);
#else
BOOST_CHECK(call_with_100(bl::bind(std_functor(std::bind(std::plus<int>(), 1, std::placeholders::_1)), _1)) == 101);
#endif
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.
bl::bind(std_functor(std::plus<int>()), _1, _2)(i, i);
bind(std_functor(std::plus<int>()), _1, _2)(i, i);
}
@@ -213,7 +189,7 @@ void test_protect()
bind(ll::for_each(), _1, _1 + 5,
protect(sum += _1))
);
BOOST_CHECK(sum == (1+15)*15/2);
BOOST_TEST(sum == (1+15)*15/2);
sum = 0;
@@ -221,17 +197,17 @@ void test_protect()
bind(ll::for_each(), _1, _1 + 5,
sum += 1 + protect(_1)) // add element count
);
BOOST_CHECK(sum == (1+15)*15/2 + 15);
BOOST_TEST(sum == (1+15)*15/2 + 15);
(1 + protect(_1))(sum);
int k = 0;
((k += constant(1)) += protect(constant(2)))();
BOOST_CHECK(k==1);
BOOST_TEST(k==1);
k = 0;
((k += constant(1)) += protect(constant(2)))()();
BOOST_CHECK(k==3);
BOOST_TEST(k==3);
// note, the following doesn't work:
@@ -289,10 +265,10 @@ void test_lambda_functors_as_arguments_to_lambda_functors() {
// sum_0() + 7, but rather
// bind(sum_0) + 7, which results in another lambda functor
// (lambda functor + int) and can be called again
BOOST_CHECK((_1 + _2)(bind(&sum_0), make_const(7))() == 7);
BOOST_TEST((_1 + _2)(bind(&sum_0), make_const(7))() == 7);
int i = 3, j = 12;
BOOST_CHECK((_1 - _2)(_2, _1)(i, j) == j - i);
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
@@ -305,12 +281,12 @@ void test_lambda_functors_as_arguments_to_lambda_functors() {
int a = 5, b = 6;
// Let type deduction find out the return type
BOOST_CHECK(bind(_1, _2, _3)(unlambda(_1 + _2), a, b) == 11);
BOOST_TEST(bind(_1, _2, _3)(unlambda(_1 + _2), a, b) == 11);
//specify it yourself:
BOOST_CHECK(bind(_1, _2, _3)(ret<int>(_1 + _2), a, b) == 11);
BOOST_CHECK(ret<int>(bind(_1, _2, _3))(_1 + _2, a, b) == 11);
BOOST_CHECK(bind<int>(_1, _2, _3)(_1 + _2, a, b) == 11);
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;
@@ -323,94 +299,28 @@ void test_const_parameters() {
// (_1 + _2)(1, 2); // this would fail,
// Either make arguments const:
BOOST_CHECK((_1 + _2)(make_const(1), make_const(2)) == 3);
BOOST_TEST((_1 + _2)(make_const(1), make_const(2)) == 3);
// Or use const_parameters:
BOOST_CHECK(const_parameters(_1 + _2)(1, 2) == 3);
BOOST_TEST(const_parameters(_1 + _2)(1, 2) == 3);
}
void test_rvalue_arguments()
{
// Not quite working yet.
// Problems with visual 7.1
// BOOST_CHECK((_1 + _2)(1, 2) == 3);
}
void test_break_const()
{
// break_const is currently unnecessary, as LL supports perfect forwarding
// for up to there argument lambda functors, and LL does not support
// lambda functors with more than 3 args.
// I'll keep the test case around anyway, if more arguments will be supported
// in the future.
// 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 and your lambda functors
// take more than 3 arguments.
// and some arguments are non-const rvalues:
// E.g.
int i = 1;
// OLD COMMENT: (_1 += _2)(i, 2) // fails, 2 is a non-const rvalue
// OLD COMMENT: const_parameters(_1 += _2)(i, 2) // fails, side-effect to i
// (_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_CHECK(i == 3);
}
template<class T>
struct func {
template<class Args>
struct sig {
typedef typename boost::tuples::element<1, Args>::type arg1;
// If the argument type is not the same as the expected type,
// return void, which will cause an error. Note that we
// can't just assert that the types are the same, because
// both const and non-const versions can be instantiated
// even though only one is ultimately used.
typedef typename boost::mpl::if_<boost::is_same<arg1, T>,
typename boost::remove_const<arg1>::type,
void
>::type type;
};
template<class U>
U operator()(const U& arg) const {
return arg;
}
};
void test_sig()
{
int i = 1;
BOOST_CHECK(bind(func<int>(), 1)() == 1);
BOOST_CHECK(bind(func<const int>(), _1)(static_cast<const int&>(i)) == 1);
BOOST_CHECK(bind(func<int>(), _1)(i) == 1);
}
class base {
public:
virtual int foo() = 0;
};
class derived : public base {
public:
virtual int foo() {
return 1;
}
};
void test_abstract()
{
derived d;
base& b = d;
BOOST_CHECK(bind(&base::foo, var(b))() == 1);
BOOST_CHECK(bind(&base::foo, *_1)(&b) == 1);
BOOST_TEST(i == 3);
}
int test_main(int, char *[]) {
@@ -420,9 +330,18 @@ int test_main(int, char *[]) {
test_protect();
test_lambda_functors_as_arguments_to_lambda_functors();
test_const_parameters();
test_rvalue_arguments();
test_break_const();
test_sig();
test_abstract();
return 0;
}

View File

@@ -1,24 +1,15 @@
// bind_tests_simple.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 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)
//
// For more information, see www.boost.org
// bind_tests_simple.cpp --------------------------------
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#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 boost::lambda;
using namespace std;
using namespace boost::lambda;
int sum_of_args_0() { return 0; }
@@ -40,18 +31,6 @@ class A {
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()
@@ -63,96 +42,71 @@ void test_member_functions()
BOOST_CHECK(bind(&A::add, ref(a), _1)(i) == 11);
BOOST_CHECK(bind(&A::add, &a, _1)(i) == 11);
BOOST_CHECK(bind(&A::add, _1, 1)(a) == 11);
BOOST_CHECK(bind(&A::add, _1, 1)(make_const(&a)) == 11);
BOOST_CHECK(bind(&A::add2, _1, 1, 1)(a) == 12);
BOOST_CHECK(bind(&A::add3, _1, 1, 1, 1)(a) == 13);
BOOST_CHECK(bind(&A::add4, _1, 1, 1, 1, 1)(a) == 14);
BOOST_CHECK(bind(&A::add5, _1, 1, 1, 1, 1, 1)(a) == 15);
BOOST_CHECK(bind(&A::add6, _1, 1, 1, 1, 1, 1, 1)(a) == 16);
BOOST_CHECK(bind(&A::add7, _1, 1, 1, 1, 1, 1, 1, 1)(a) == 17);
BOOST_CHECK(bind(&A::add8, _1, 1, 1, 1, 1, 1, 1, 1, 1)(a) == 18);
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);
}
struct B {
B(int n) : i(n) {};
int i;
};
void test_data_members()
{
using boost::ref;
B b(10);
BOOST_CHECK(bind(&B::i, ref(b))() == 10);
BOOST_CHECK(bind(&B::i, b)() == 10);
BOOST_CHECK(bind(&B::i, _1)(b) == 10);
BOOST_CHECK(bind(&B::i, _1)(B(11)) == 11);
bind(&B::i, ref(b))() = 1;
BOOST_CHECK(b.i == 1);
}
int test_main(int, char *[]) {
int i = 1; int j = 2; int k = 3;
int result;
// bind all parameters
BOOST_CHECK(bind(&sum_of_args_0)()==0);
BOOST_CHECK(bind(&sum_of_args_1, 1)()==1);
BOOST_CHECK(bind(&sum_of_args_2, 1, 2)()==3);
BOOST_CHECK(bind(&sum_of_args_3, 1, 2, 3)()==6);
BOOST_CHECK(bind(&sum_of_args_4, 1, 2, 3, 4)()==10);
BOOST_CHECK(bind(&sum_of_args_5, 1, 2, 3, 4, 5)()==15);
BOOST_CHECK(bind(&sum_of_args_6, 1, 2, 3, 4, 5, 6)()==21);
BOOST_CHECK(bind(&sum_of_args_7, 1, 2, 3, 4, 5, 6, 7)()==28);
BOOST_CHECK(bind(&sum_of_args_8, 1, 2, 3, 4, 5, 6, 7, 8)()==36);
BOOST_CHECK(bind(&sum_of_args_9, 1, 2, 3, 4, 5, 6, 7, 8, 9)()==45);
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_CHECK(bind(&sum_of_args_0)()==0);
BOOST_CHECK(bind(&sum_of_args_1, _1)(i)==1);
BOOST_CHECK(bind(&sum_of_args_2, _1, 2)(i)==3);
BOOST_CHECK(bind(&sum_of_args_3, _1, 2, 3)(i)==6);
BOOST_CHECK(bind(&sum_of_args_4, _1, 2, 3, 4)(i)==10);
BOOST_CHECK(bind(&sum_of_args_5, _1, 2, 3, 4, 5)(i)==15);
BOOST_CHECK(bind(&sum_of_args_6, _1, 2, 3, 4, 5, 6)(i)==21);
BOOST_CHECK(bind(&sum_of_args_7, _1, 2, 3, 4, 5, 6, 7)(i)==28);
BOOST_CHECK(bind(&sum_of_args_8, _1, 2, 3, 4, 5, 6, 7, 8)(i)==36);
BOOST_CHECK(bind(&sum_of_args_9, _1, 2, 3, 4, 5, 6, 7, 8, 9)(i)==45);
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_CHECK(bind(&sum_of_args_0)()==0);
BOOST_CHECK(bind(&sum_of_args_1, _1)(i)==1);
BOOST_CHECK(bind(&sum_of_args_2, _1, _2)(i, j)==3);
BOOST_CHECK(bind(&sum_of_args_3, _1, _2, 3)(i, j)==6);
BOOST_CHECK(bind(&sum_of_args_4, _1, _2, 3, 4)(i, j)==10);
BOOST_CHECK(bind(&sum_of_args_5, _1, _2, 3, 4, 5)(i, j)==15);
BOOST_CHECK(bind(&sum_of_args_6, _1, _2, 3, 4, 5, 6)(i, j)==21);
BOOST_CHECK(bind(&sum_of_args_7, _1, _2, 3, 4, 5, 6, 7)(i, j)==28);
BOOST_CHECK(bind(&sum_of_args_8, _1, _2, 3, 4, 5, 6, 7, 8)(i, j)==36);
BOOST_CHECK(bind(&sum_of_args_9, _1, _2, 3, 4, 5, 6, 7, 8, 9)(i, j)==45);
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_CHECK(bind(&sum_of_args_0)()==0);
BOOST_CHECK(bind(&sum_of_args_1, _1)(i)==1);
BOOST_CHECK(bind(&sum_of_args_2, _1, _2)(i, j)==3);
BOOST_CHECK(bind(&sum_of_args_3, _1, _2, _3)(i, j, k)==6);
BOOST_CHECK(bind(&sum_of_args_4, _1, _2, _3, 4)(i, j, k)==10);
BOOST_CHECK(bind(&sum_of_args_5, _1, _2, _3, 4, 5)(i, j, k)==15);
BOOST_CHECK(bind(&sum_of_args_6, _1, _2, _3, 4, 5, 6)(i, j, k)==21);
BOOST_CHECK(bind(&sum_of_args_7, _1, _2, _3, 4, 5, 6, 7)(i, j, k)==28);
BOOST_CHECK(bind(&sum_of_args_8, _1, _2, _3, 4, 5, 6, 7, 8)(i, j, k)==36);
BOOST_CHECK(bind(&sum_of_args_9, _1, _2, _3, 4, 5, 6, 7, 8, 9)(i, j, k)==45);
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_CHECK(bind(&sum_of_args_3, bind(&sum_of_args_2, _1, 2), 2, 3)(i)==8);
BOOST_CHECK(
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
@@ -178,7 +132,7 @@ int test_main(int, char *[]) {
_3,
4)
)(i, j, k);
BOOST_CHECK(result == 12);
BOOST_TEST(result == 12);
test_member_functions();

View File

@@ -1,24 +1,15 @@
// bind_tests_simple.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 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)
//
// For more information, see www.boost.org
// bind_tests_simple.cpp --------------------------------
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#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 boost::lambda;
using namespace std;
using namespace boost::lambda;
int sum_of_args_0() { return 0; }
@@ -48,10 +39,10 @@ void test_member_functions()
A a(10);
int i = 1;
BOOST_CHECK(bind(&A::add, ref(a), _1)(i) == 11);
BOOST_CHECK(bind(&A::add, &a, _1)(i) == 11);
BOOST_CHECK(bind(&A::add, _1, 1)(a) == 11);
BOOST_CHECK(bind(&A::add, _1, 1)(make_const(&a)) == 11);
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);
@@ -64,56 +55,56 @@ int test_main(int, char *[]) {
// bind all parameters
BOOST_CHECK(bind(sum_of_args_0)()==0);
BOOST_CHECK(bind(sum_of_args_1, 1)()==1);
BOOST_CHECK(bind(sum_of_args_2, 1, 2)()==3);
BOOST_CHECK(bind(sum_of_args_3, 1, 2, 3)()==6);
BOOST_CHECK(bind(sum_of_args_4, 1, 2, 3, 4)()==10);
BOOST_CHECK(bind(sum_of_args_5, 1, 2, 3, 4, 5)()==15);
BOOST_CHECK(bind(sum_of_args_6, 1, 2, 3, 4, 5, 6)()==21);
BOOST_CHECK(bind(sum_of_args_7, 1, 2, 3, 4, 5, 6, 7)()==28);
BOOST_CHECK(bind(sum_of_args_8, 1, 2, 3, 4, 5, 6, 7, 8)()==36);
BOOST_CHECK(bind(sum_of_args_9, 1, 2, 3, 4, 5, 6, 7, 8, 9)()==45);
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_CHECK(bind(sum_of_args_0)()==0);
BOOST_CHECK(bind(sum_of_args_1, _1)(i)==1);
BOOST_CHECK(bind(sum_of_args_2, _1, 2)(i)==3);
BOOST_CHECK(bind(sum_of_args_3, _1, 2, 3)(i)==6);
BOOST_CHECK(bind(sum_of_args_4, _1, 2, 3, 4)(i)==10);
BOOST_CHECK(bind(sum_of_args_5, _1, 2, 3, 4, 5)(i)==15);
BOOST_CHECK(bind(sum_of_args_6, _1, 2, 3, 4, 5, 6)(i)==21);
BOOST_CHECK(bind(sum_of_args_7, _1, 2, 3, 4, 5, 6, 7)(i)==28);
BOOST_CHECK(bind(sum_of_args_8, _1, 2, 3, 4, 5, 6, 7, 8)(i)==36);
BOOST_CHECK(bind(sum_of_args_9, _1, 2, 3, 4, 5, 6, 7, 8, 9)(i)==45);
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_CHECK(bind(sum_of_args_0)()==0);
BOOST_CHECK(bind(sum_of_args_1, _1)(i)==1);
BOOST_CHECK(bind(sum_of_args_2, _1, _2)(i, j)==3);
BOOST_CHECK(bind(sum_of_args_3, _1, _2, 3)(i, j)==6);
BOOST_CHECK(bind(sum_of_args_4, _1, _2, 3, 4)(i, j)==10);
BOOST_CHECK(bind(sum_of_args_5, _1, _2, 3, 4, 5)(i, j)==15);
BOOST_CHECK(bind(sum_of_args_6, _1, _2, 3, 4, 5, 6)(i, j)==21);
BOOST_CHECK(bind(sum_of_args_7, _1, _2, 3, 4, 5, 6, 7)(i, j)==28);
BOOST_CHECK(bind(sum_of_args_8, _1, _2, 3, 4, 5, 6, 7, 8)(i, j)==36);
BOOST_CHECK(bind(sum_of_args_9, _1, _2, 3, 4, 5, 6, 7, 8, 9)(i, j)==45);
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_CHECK(bind(sum_of_args_0)()==0);
BOOST_CHECK(bind(sum_of_args_1, _1)(i)==1);
BOOST_CHECK(bind(sum_of_args_2, _1, _2)(i, j)==3);
BOOST_CHECK(bind(sum_of_args_3, _1, _2, _3)(i, j, k)==6);
BOOST_CHECK(bind(sum_of_args_4, _1, _2, _3, 4)(i, j, k)==10);
BOOST_CHECK(bind(sum_of_args_5, _1, _2, _3, 4, 5)(i, j, k)==15);
BOOST_CHECK(bind(sum_of_args_6, _1, _2, _3, 4, 5, 6)(i, j, k)==21);
BOOST_CHECK(bind(sum_of_args_7, _1, _2, _3, 4, 5, 6, 7)(i, j, k)==28);
BOOST_CHECK(bind(sum_of_args_8, _1, _2, _3, 4, 5, 6, 7, 8)(i, j, k)==36);
BOOST_CHECK(bind(sum_of_args_9, _1, _2, _3, 4, 5, 6, 7, 8, 9)(i, j, k)==45);
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_CHECK(bind(sum_of_args_3, bind(sum_of_args_2, _1, 2), 2, 3)(i)==8);
BOOST_CHECK(
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
@@ -139,7 +130,7 @@ int test_main(int, char *[]) {
_3,
4)
)(i, j, k);
BOOST_CHECK(result == 12);
BOOST_TEST(result == 12);
test_member_functions();

View File

@@ -1,17 +1,9 @@
// bll_and_function.cpp - The Boost Lambda Library -----------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 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)
//
// For more information, see www.boost.org
// bll_and_function.cpp --------------------------------
// test using BLL and boost::function
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#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"
@@ -29,23 +21,23 @@ using namespace std;
void test_function() {
boost::function<int (int, int)> f;
boost::function<int, int, int> f;
f = _1 + _2;
BOOST_CHECK(f(1, 2)== 3);
BOOST_TEST(f(1, 2)== 3);
int i=1; int j=2;
boost::function<int& (int&, int)> g = _1 += _2;
boost::function<int&, int&, int> g = _1 += _2;
g(i, j);
BOOST_CHECK(i==3);
BOOST_TEST(i==3);
int* sum = new int();
*sum = 0;
boost::function<int& (int)> counter = *sum += _1;
boost::function<int&, int> counter = *sum += _1;
counter(5); // ok, sum* = 5;
BOOST_CHECK(*sum == 5);
BOOST_TEST(*sum == 5);
delete sum;
// The next statement would lead to a dangling reference

View File

@@ -1,18 +1,7 @@
// cast_tests.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 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)
//
// For more information, see www.boost.org
// cast_tests.cpp --------------------------------
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#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"
@@ -29,7 +18,7 @@ class base {
public:
virtual std::string class_name() const { return "const base"; }
virtual std::string class_name() { return "base"; }
virtual ~base() {}
};
class derived : public base {
@@ -53,46 +42,46 @@ void do_test() {
(var(b) = ll_static_cast<base *>(p_derived))();
(var(d) = ll_static_cast<derived *>(b))();
BOOST_CHECK(b->class_name() == "derived");
BOOST_CHECK(d->class_name() == "derived");
BOOST_TEST(b->class_name() == "derived");
BOOST_TEST(d->class_name() == "derived");
(var(b) = ll_dynamic_cast<derived *>(b))();
BOOST_CHECK(b != 0);
BOOST_CHECK(b->class_name() == "derived");
BOOST_TEST(b != 0);
BOOST_TEST(b->class_name() == "derived");
(var(d) = ll_dynamic_cast<derived *>(p_base))();
BOOST_CHECK(d == 0);
BOOST_TEST(d == 0);
const derived* p_const_derived = p_derived;
BOOST_CHECK(p_const_derived->class_name() == "const derived");
BOOST_TEST(p_const_derived->class_name() == "const derived");
(var(d) = ll_const_cast<derived *>(p_const_derived))();
BOOST_CHECK(d->class_name() == "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_CHECK(*ip == 10);
BOOST_TEST(*ip == 10);
// typeid
BOOST_CHECK(string(ll_typeid(d)().name()) == string(typeid(d).name()));
BOOST_TEST(string(ll_typeid(d)().name()) == string(typeid(d).name()));
// sizeof
BOOST_CHECK(ll_sizeof(_1)(p_derived) == sizeof(p_derived));
BOOST_CHECK(ll_sizeof(_1)(*p_derived) == sizeof(*p_derived));
BOOST_CHECK(ll_sizeof(_1)(p_base) == sizeof(p_base));
BOOST_CHECK(ll_sizeof(_1)(*p_base) == sizeof(*p_base));
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_CHECK(ll_sizeof(_1)(an_array) == 100 * sizeof(int));
BOOST_TEST(ll_sizeof(_1)(an_array) == 100 * sizeof(int));
delete p_derived;
delete p_base;

View File

@@ -1,18 +1,7 @@
// constructor_tests.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 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)
//
// For more information, see www.boost.org
// constructor_tests.cpp --------------------------------
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#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"
@@ -24,12 +13,8 @@
#include <algorithm>
#include <vector>
#ifdef BOOST_MSVC
#pragma warning(disable:4512)
#endif
using namespace boost::lambda;
namespace bl = boost::lambda;
using namespace std;
template<class T>
bool check_tuple(int n, const T& t)
@@ -38,7 +23,7 @@ bool check_tuple(int n, const T& t)
}
template <>
bool check_tuple(int /*n*/, const null_type& ) { return true; }
bool check_tuple(int n, const null_type& ) { return true; }
void constructor_all_lengths()
@@ -49,63 +34,63 @@ void constructor_all_lengths()
bind(constructor<tuple<int> >(),
1)()
);
BOOST_CHECK(ok);
BOOST_TEST(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int> >(),
1, 2)()
);
BOOST_CHECK(ok);
BOOST_TEST(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int> >(),
1, 2, 3)()
);
BOOST_CHECK(ok);
BOOST_TEST(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int, int> >(),
1, 2, 3, 4)()
);
BOOST_CHECK(ok);
BOOST_TEST(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int, int, int> >(),
1, 2, 3, 4, 5)()
);
BOOST_CHECK(ok);
BOOST_TEST(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6)()
);
BOOST_CHECK(ok);
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_CHECK(ok);
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_CHECK(ok);
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_CHECK(ok);
BOOST_TEST(ok);
}
@@ -117,63 +102,63 @@ void new_ptr_all_lengths()
*(bind(new_ptr<tuple<int> >(),
1))()
);
BOOST_CHECK(ok);
BOOST_TEST(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int> >(),
1, 2))()
);
BOOST_CHECK(ok);
BOOST_TEST(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int> >(),
1, 2, 3))()
);
BOOST_CHECK(ok);
BOOST_TEST(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int, int> >(),
1, 2, 3, 4))()
);
BOOST_CHECK(ok);
BOOST_TEST(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int, int, int> >(),
1, 2, 3, 4, 5))()
);
BOOST_CHECK(ok);
BOOST_TEST(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6))()
);
BOOST_CHECK(ok);
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_CHECK(ok);
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_CHECK(ok);
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_CHECK(ok);
BOOST_TEST(ok);
}
@@ -187,17 +172,17 @@ public:
void test_destructor ()
{
char space[sizeof(is_destructor_called)];
bool flag = false;
bool flag;
is_destructor_called* idc = new(space) is_destructor_called(flag);
BOOST_CHECK(flag == false);
BOOST_TEST(flag == false);
bind(destructor(), _1)(idc);
BOOST_CHECK(flag == true);
BOOST_TEST(flag == true);
idc = new(space) is_destructor_called(flag);
BOOST_CHECK(flag == false);
BOOST_TEST(flag == false);
bind(destructor(), _1)(*idc);
BOOST_CHECK(flag == true);
BOOST_TEST(flag == true);
}
@@ -212,18 +197,18 @@ int count_deletes::count = 0;
void test_news_and_deletes ()
{
int* i[10];
std::for_each(i, i+10, _1 = bind(new_ptr<int>(), 2));
for_each(i, i+10, _1 = bind(new_ptr<int>(), 2));
int count_errors = 0;
std::for_each(i, i+10, (*_1 == 2) || ++var(count_errors));
BOOST_CHECK(count_errors == 0);
for_each(i, i+10, (*_1 == 2) || ++var(count_errors));
BOOST_TEST(count_errors == 0);
count_deletes* ct[10];
std::for_each(ct, ct+10, _1 = bind(new_ptr<count_deletes>()));
for_each(ct, ct+10, _1 = bind(new_ptr<count_deletes>()));
count_deletes::count = 0;
std::for_each(ct, ct+10, bind(delete_ptr(), _1));
BOOST_CHECK(count_deletes::count == 10);
for_each(ct, ct+10, bind(delete_ptr(), _1));
BOOST_TEST(count_deletes::count == 10);
}
@@ -234,22 +219,22 @@ void test_array_new_and_delete()
count_deletes::count = 0;
bind(delete_array(), _1)(c);
BOOST_CHECK(count_deletes::count == 5);
BOOST_TEST(count_deletes::count == 5);
}
void delayed_construction()
{
std::vector<int> x(3);
std::vector<int> y(3);
vector<int> x(3);
vector<int> y(3);
std::fill(x.begin(), x.end(), 0);
std::fill(y.begin(), y.end(), 1);
fill(x.begin(), x.end(), 0);
fill(y.begin(), y.end(), 1);
std::vector<std::pair<int, int> > v;
vector<pair<int, int> > v;
std::transform(x.begin(), x.end(), y.begin(), std::back_inserter(v),
bl::bind(constructor<std::pair<int, int> >(), _1, _2) );
transform(x.begin(), x.end(), y.begin(), back_inserter(v),
bind(constructor<pair<int, int> >(), _1, _2) );
}
int test_main(int, char *[]) {

View File

@@ -1,17 +1,5 @@
// -- control_structures.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 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)
//
// For more information, see www.boost.org
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#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"
@@ -22,18 +10,7 @@
#include <vector>
using namespace boost;
using boost::lambda::constant;
using boost::lambda::_1;
using boost::lambda::_2;
using boost::lambda::_3;
using boost::lambda::make_const;
using boost::lambda::for_loop;
using boost::lambda::while_loop;
using boost::lambda::do_while_loop;
using boost::lambda::if_then;
using boost::lambda::if_then_else;
using boost::lambda::if_then_else_return;
using namespace boost::lambda;
// 2 container for_each
template <class InputIter1, class InputIter2, class Function>
@@ -50,41 +27,41 @@ void simple_loops() {
int i;
int arithmetic_series = 0;
for_loop(_1 = 0, _1 < 10, _1++, arithmetic_series += _1)(i);
BOOST_CHECK(arithmetic_series == 45);
BOOST_TEST(arithmetic_series == 45);
// no body case
for_loop(boost::lambda::var(i) = 0, boost::lambda::var(i) < 100, ++boost::lambda::var(i))();
BOOST_CHECK(i == 100);
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_CHECK(c == 3);
BOOST_TEST(c == 3);
int count;
count = 0; i = 0;
while_loop(_1++ < 10, ++boost::lambda::var(count))(i);
BOOST_CHECK(count == 10);
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, ++boost::lambda::var(count))(i);
BOOST_CHECK(count == 11);
do_while_loop(_1++ < 10, ++var(count))(i);
BOOST_TEST(count == 11);
a = 0;
do_while_loop(constant(false), _1++)(a);
BOOST_CHECK(a == 1);
BOOST_TEST(a == 1);
// no body cases
a = 40; b = 30;
while_loop(--_1 > _2)(a, b);
BOOST_CHECK(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_CHECK(a == b);
BOOST_TEST(a == b);
}
@@ -93,25 +70,25 @@ void simple_ifs () {
int value = 42;
if_then(_1 < 0, _1 = 0)(value);
BOOST_CHECK(value == 42);
BOOST_TEST(value == 42);
value = -42;
if_then(_1 < 0, _1 = -_1)(value);
BOOST_CHECK(value == 42);
BOOST_TEST(value == 42);
int min;
if_then_else(_1 < _2, boost::lambda::var(min) = _1, boost::lambda::var(min) = _2)
if_then_else(_1 < _2, var(min) = _1, var(min) = _2)
(make_const(1), make_const(2));
BOOST_CHECK(min == 1);
BOOST_TEST(min == 1);
if_then_else(_1 < _2, boost::lambda::var(min) = _1, boost::lambda::var(min) = _2)
if_then_else(_1 < _2, var(min) = _1, var(min) = _2)
(make_const(5), make_const(3));
BOOST_CHECK(min == 3);
BOOST_TEST(min == 3);
int x, y;
x = -1; y = 1;
BOOST_CHECK(if_then_else_return(_1 < _2, _2, _1)(x, y) == (std::max)(x ,y));
BOOST_CHECK(if_then_else_return(_1 < _2, _2, _1)(y, x) == (std::max)(x ,y));
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));
}

View File

@@ -1,17 +1,5 @@
// -- exception_test.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 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)
//
// For more information, see www.boost.org
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#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"
@@ -29,7 +17,7 @@ using namespace boost::lambda;
using namespace std;
// to prevent unused variables warnings
template <class T> void dummy(const T&) {}
template <class T> void dummy(const T& t) {}
void erroneous_exception_related_lambda_expressions() {
@@ -98,7 +86,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_CHECK(ecount == 1);
BOOST_TEST(ecount == 1);
ecount = 0;
for(int i=1; i<=2; i++)
@@ -113,7 +101,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_CHECK(ecount == 2);
BOOST_TEST(ecount == 2);
ecount = 0;
for(int i=1; i<=3; i++)
@@ -131,7 +119,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_CHECK(ecount == 3);
BOOST_TEST(ecount == 3);
ecount = 0;
for(int i=1; i<=4; i++)
@@ -152,7 +140,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_CHECK(ecount == 4);
BOOST_TEST(ecount == 4);
ecount = 0;
for(int i=1; i<=5; i++)
@@ -176,7 +164,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_CHECK(ecount == 5);
BOOST_TEST(ecount == 5);
ecount = 0;
for(int i=1; i<=6; i++)
@@ -203,7 +191,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_CHECK(ecount == 6);
BOOST_TEST(ecount == 6);
ecount = 0;
for(int i=1; i<=7; i++)
@@ -233,7 +221,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_CHECK(ecount == 7);
BOOST_TEST(ecount == 7);
ecount = 0;
for(int i=1; i<=8; i++)
@@ -266,7 +254,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_CHECK(ecount == 8);
BOOST_TEST(ecount == 8);
ecount = 0;
for(int i=1; i<=9; i++)
@@ -302,7 +290,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_CHECK(ecount == 9);
BOOST_TEST(ecount == 9);
// with catch(...) blocks
@@ -317,7 +305,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_CHECK(ecount == 1);
BOOST_TEST(ecount == 1);
ecount = 0;
for(int i=1; i<=2; i++)
@@ -332,7 +320,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_CHECK(ecount == 2);
BOOST_TEST(ecount == 2);
ecount = 0;
for(int i=1; i<=3; i++)
@@ -350,7 +338,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_CHECK(ecount == 3);
BOOST_TEST(ecount == 3);
ecount = 0;
for(int i=1; i<=4; i++)
@@ -371,7 +359,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_CHECK(ecount == 4);
BOOST_TEST(ecount == 4);
ecount = 0;
for(int i=1; i<=5; i++)
@@ -395,7 +383,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_CHECK(ecount == 5);
BOOST_TEST(ecount == 5);
ecount = 0;
for(int i=1; i<=6; i++)
@@ -422,7 +410,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_CHECK(ecount == 6);
BOOST_TEST(ecount == 6);
ecount = 0;
for(int i=1; i<=7; i++)
@@ -452,7 +440,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_CHECK(ecount == 7);
BOOST_TEST(ecount == 7);
ecount = 0;
for(int i=1; i<=8; i++)
@@ -485,7 +473,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_CHECK(ecount == 8);
BOOST_TEST(ecount == 8);
ecount = 0;
for(int i=1; i<=9; i++)
@@ -521,7 +509,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_CHECK(ecount == 9);
BOOST_TEST(ecount == 9);
}
void test_empty_catch_blocks() {
@@ -551,7 +539,7 @@ void return_type_matching() {
int i = 1;
BOOST_CHECK(
BOOST_TEST(
try_catch(
_1 + 1,
@@ -575,14 +563,14 @@ void return_type_matching() {
make_void(_1 += 1),
catch_exception<char>(_e) // since try is void, catch can return anything
)(i);
BOOST_CHECK(i == 2);
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_CHECK(i == 3);
BOOST_TEST(i == 3);
char a = 'a';
try_catch(
@@ -592,7 +580,7 @@ void return_type_matching() {
),
catch_exception<char>( _1 = _e )
)(a);
BOOST_CHECK(a == 'b');
BOOST_TEST(a == 'b');
}
int test_main(int, char *[]) {
@@ -603,13 +591,13 @@ int test_main(int, char *[]) {
return_type_matching();
test_empty_catch_blocks();
}
catch (int)
catch (int x)
{
BOOST_CHECK(false);
BOOST_TEST(false);
}
catch(...)
{
BOOST_CHECK(false);
BOOST_TEST(false);
}

View File

@@ -1,22 +1,10 @@
// extending_return_type_traits.cpp -- The Boost Lambda Library --------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 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)
//
// For more information, see www.boost.org
// extending_return_type_traits.cpp --------------------------------
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#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 "boost/lambda/detail/suppress_unused.hpp"
#include <iostream>
@@ -24,8 +12,6 @@
#include <algorithm>
using boost::lambda::detail::suppress_unused_variable_warnings;
class A {};
class B {};
@@ -84,7 +70,7 @@ struct plain_return_type_1<other_action<contentsof_action>, A> {
} // lambda
} // boost
void ok(B /*b*/) {}
void ok(B b) {}
void test_unary_operators()
{
@@ -99,7 +85,7 @@ void test_unary_operators()
ok((&_1)(a));
ok((*_1)(a));
BOOST_CHECK((*_1)(make_const(&i)) == 1);
BOOST_TEST((*_1)(make_const(&i)) == 1);
}
class X {};
@@ -130,7 +116,7 @@ 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*/)
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;
@@ -178,8 +164,8 @@ Z operator^=( X&, const Y&) { return Z(); }
// assignment
class Assign {
public:
void operator=(const Assign& /*a*/) {}
X operator[](const int& /*i*/) { return X(); }
void operator=(const Assign& a) {}
X operator[](const int& i) { return X(); }
};
@@ -332,16 +318,9 @@ void test_binary_operators() {
XX dummy3 = (_1 * _2)(vxx, vyy);
VV dummy4 = (_1 * _2)(cvxx, cvyy);
suppress_unused_variable_warnings(dummy1);
suppress_unused_variable_warnings(dummy2);
suppress_unused_variable_warnings(dummy3);
suppress_unused_variable_warnings(dummy4);
my_vector<int> v1; my_vector<double> v2;
my_vector<double> d = (_1 + _2)(v1, v2);
suppress_unused_variable_warnings(d);
// bitwise
(_1 << _2)(x, y);

View File

@@ -1,18 +1,7 @@
// is_instance_of_test.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 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)
//
// For more information, see www.boost.org
// is_convertible_to_template_test.cpp ----------------------------
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#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"
@@ -53,25 +42,25 @@ using boost::lambda::is_instance_of_3;
using boost::lambda::is_instance_of_4;
BOOST_CHECK((is_instance_of_1<B1, A1>::value == true));
BOOST_CHECK((is_instance_of_1<A1<float>, A1>::value == true));
BOOST_CHECK((is_instance_of_1<int, A1>::value == false));
BOOST_CHECK((is_instance_of_1<C1, A1>::value == false));
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_CHECK((is_instance_of_2<B2, A2>::value == true));
BOOST_CHECK((is_instance_of_2<A2<int, float>, A2>::value == true));
BOOST_CHECK((is_instance_of_2<int, A2>::value == false));
BOOST_CHECK((is_instance_of_2<C2, A2>::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_CHECK((is_instance_of_3<B3, A3>::value == true));
BOOST_CHECK((is_instance_of_3<A3<int, float, char>, A3>::value == true));
BOOST_CHECK((is_instance_of_3<int, A3>::value == false));
BOOST_CHECK((is_instance_of_3<C3, A3>::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_CHECK((is_instance_of_4<B4, A4>::value == true));
BOOST_CHECK((is_instance_of_4<A4<int, float, char, double>, A4>::value == true));
BOOST_CHECK((is_instance_of_4<int, A4>::value == false));
BOOST_CHECK((is_instance_of_4<C4, A4>::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;

View File

@@ -1,30 +0,0 @@
// istreambuf_test - test lambda function objects with istreambuf_iterator
//
// Copyright (c) 2007 Peter Dimov
//
// 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
#include <boost/lambda/lambda.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <iterator>
#include <sstream>
#include <algorithm>
int main()
{
using namespace boost::lambda;
std::stringstream is( "ax2" );
std::istreambuf_iterator<char> b2( is );
std::istreambuf_iterator<char> e2;
std::istreambuf_iterator<char> i = std::find_if( b2, e2, _1 == 'x' );
BOOST_TEST( *i == 'x' );
BOOST_TEST( std::distance( i, e2 ) == 2 );
return boost::report_errors();
}

View File

@@ -1,18 +1,7 @@
// member_pointer_test.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 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)
//
// For more information, see www.boost.org
// member_pointer_test.cpp --------------------------------
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#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"
@@ -50,65 +39,65 @@ void pointer_to_data_member_tests() {
// int i = 0;
my_struct *y = &x;
BOOST_CHECK((_1 ->* &my_struct::mem)(y) == 3);
BOOST_TEST((_1 ->* &my_struct::mem)(y) == 3);
(_1 ->* &my_struct::mem)(y) = 4;
BOOST_CHECK(x.mem == 4);
BOOST_TEST(x.mem == 4);
((_1 ->* &my_struct::mem) = 5)(y);
BOOST_CHECK(x.mem == 5);
BOOST_TEST(x.mem == 5);
// &my_struct::mem is a temporary, must be constified
((y ->* _1) = 6)(make_const(&my_struct::mem));
BOOST_CHECK(x.mem == 6);
BOOST_TEST(x.mem == 6);
((_1 ->* _2) = 7)(y, make_const(&my_struct::mem));
BOOST_CHECK(x.mem == 7);
BOOST_TEST(x.mem == 7);
}
void pointer_to_member_function_tests() {
my_struct *y = new my_struct(1);
BOOST_CHECK( (_1 ->* &my_struct::foo)(y)() == (y->mem));
BOOST_CHECK( (_1 ->* &my_struct::fooc)(y)() == (y->mem));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo))() == (y->mem));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::fooc))() == (y->mem));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo))() == (y->mem));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::fooc))() == (y->mem));
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_CHECK( (_1 ->* &my_struct::foo1)(y)(1) == (y->mem+1));
BOOST_CHECK( (_1 ->* &my_struct::foo1c)(y)(1) == (y->mem+1));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo1))(1) == (y->mem+1));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo1c))(1) == (y->mem+1));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo1))(1) == (y->mem+1));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo1c))(1) == (y->mem+1));
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_CHECK( (_1 ->* &my_struct::foo2)(y)(1,2) == (y->mem+1+2));
BOOST_CHECK( (_1 ->* &my_struct::foo2c)(y)(1,2) == (y->mem+1+2));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo2))(1,2) == (y->mem+1+2));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo2c))(1,2) == (y->mem+1+2));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo2))(1,2) == (y->mem+1+2));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo2c))(1,2) == (y->mem+1+2));
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_CHECK( (_1 ->* &my_struct::foo3)(y)(1,2,3) == (y->mem+1+2+3));
BOOST_CHECK( (_1 ->* &my_struct::foo3c)(y)(1,2,3) == (y->mem+1+2+3));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo3))(1,2,3) == (y->mem+1+2+3));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo3c))(1,2,3) == (y->mem+1+2+3));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo3))(1,2,3) == (y->mem+1+2+3));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo3c))(1,2,3) == (y->mem+1+2+3));
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_CHECK( (_1 ->* &my_struct::foo4)(y)(1,2,3,4) == (y->mem+1+2+3+4));
BOOST_CHECK( (_1 ->* &my_struct::foo4c)(y)(1,2,3,4) == (y->mem+1+2+3+4));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo4))(1,2,3,4) == (y->mem+1+2+3+4));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo4c))(1,2,3,4) == (y->mem+1+2+3+4));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo4))(1,2,3,4) == (y->mem+1+2+3+4));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo4c))(1,2,3,4) == (y->mem+1+2+3+4));
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_CHECK( (_1 ->* &my_struct::foo3default)(y)() == (y->mem+1+2+3));
// BOOST_TEST( (_1 ->* &my_struct::foo3default)(y)() == (y->mem+1+2+3));
}
@@ -118,11 +107,11 @@ class C {};
class D {};
// ->* can be overloaded to do anything
bool operator->*(A /*a*/, B /*b*/) {
bool operator->*(A a, B b) {
return false;
}
bool operator->*(B /*b*/, A /*a*/) {
bool operator->*(B b, A a) {
return true;
}
@@ -163,21 +152,21 @@ void test_overloaded_pointer_to_member()
A a; B b;
// this won't work, can't deduce the return type
// BOOST_CHECK((_1->*_2)(a, b) == false);
// BOOST_TEST((_1->*_2)(a, b) == false);
// ret<bool> gives the return type
BOOST_CHECK(ret<bool>(_1->*_2)(a, b) == false);
BOOST_CHECK(ret<bool>(a->*_1)(b) == false);
BOOST_CHECK(ret<bool>(_1->*b)(a) == false);
BOOST_CHECK((ret<bool>((var(a))->*b))() == false);
BOOST_CHECK((ret<bool>((var(a))->*var(b)))() == false);
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_CHECK((_1->*_2)(b, a) == true);
BOOST_CHECK((b->*_1)(a) == true);
BOOST_CHECK((_1->*a)(b) == true);
BOOST_CHECK((var(b)->*a)() == true);
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;
}

View File

@@ -1,26 +1,10 @@
// operator_tests_simple.cpp -- The Boost Lambda Library ---------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 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)
//
// For more information, see www.boost.org
// operator_tests_simple.cpp --------------------------------
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#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/detail/suppress_unused.hpp"
#include <boost/shared_ptr.hpp>
#include <vector>
#include <map>
#include <set>
@@ -51,7 +35,7 @@ void cout_tests()
(os << constant("FOO"))();
BOOST_CHECK(os.str() == std::string("10FOO"));
BOOST_TEST(os.str() == std::string("10FOO"));
istringstream is("ABC 1");
@@ -61,21 +45,21 @@ void cout_tests()
is >> s;
is >> k;
BOOST_CHECK(s == std::string("ABC"));
BOOST_CHECK(k == 1);
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_CHECK((ci)() == 5);
BOOST_CHECK(i == 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_CHECK(i == 101);
BOOST_TEST(i == 101);
#endif
}
@@ -85,117 +69,115 @@ void arithmetic_operators() {
using namespace std;
using namespace boost::lambda;
BOOST_CHECK((_1 + 1)(i)==2);
BOOST_CHECK(((_1 + 1) * _2)(i, j)==4);
BOOST_CHECK((_1 - 1)(i)==0);
BOOST_TEST((_1 + 1)(i)==2);
BOOST_TEST(((_1 + 1) * _2)(i, j)==4);
BOOST_TEST((_1 - 1)(i)==0);
BOOST_CHECK((_1 * 2)(j)==4);
BOOST_CHECK((_1 / 2)(j)==1);
BOOST_TEST((_1 * 2)(j)==4);
BOOST_TEST((_1 / 2)(j)==1);
BOOST_CHECK((_1 % 2)(k)==1);
BOOST_TEST((_1 % 2)(k)==1);
BOOST_CHECK((-_1)(i) == -1);
BOOST_CHECK((+_1)(i) == 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);
boost::lambda::detail::suppress_unused_variable_warnings(up);
}
void bitwise_operators() {
unsigned int ui = 2;
BOOST_CHECK((_1 << 1)(ui)==(2 << 1));
BOOST_CHECK((_1 >> 1)(ui)==(2 >> 1));
BOOST_TEST((_1 << 1)(ui)==(2 << 1));
BOOST_TEST((_1 >> 1)(ui)==(2 >> 1));
BOOST_CHECK((_1 & 1)(ui)==(2 & 1));
BOOST_CHECK((_1 | 1)(ui)==(2 | 1));
BOOST_CHECK((_1 ^ 1)(ui)==(2 ^ 1));
BOOST_CHECK((~_1)(ui)==~2u);
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_CHECK((_1 < _2)(i, j) == true);
BOOST_CHECK((_1 <= _2)(i, j) == true);
BOOST_CHECK((_1 == _2)(i, j) == false);
BOOST_CHECK((_1 != _2)(i, j) == true);
BOOST_CHECK((_1 > _2)(i, j) == false);
BOOST_CHECK((_1 >= _2)(i, j) == false);
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_CHECK((!(_1 < _2))(i, j) == false);
BOOST_CHECK((!(_1 <= _2))(i, j) == false);
BOOST_CHECK((!(_1 == _2))(i, j) == true);
BOOST_CHECK((!(_1 != _2))(i, j) == false);
BOOST_CHECK((!(_1 > _2))(i, j) == true);
BOOST_CHECK((!(_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) == 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_CHECK((_1 && _2)(t, t) == true);
BOOST_CHECK((_1 && _2)(t, f) == false);
BOOST_CHECK((_1 && _2)(f, t) == false);
BOOST_CHECK((_1 && _2)(f, 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_CHECK((_1 || _2)(t, t) == true);
BOOST_CHECK((_1 || _2)(t, f) == true);
BOOST_CHECK((_1 || _2)(f, t) == true);
BOOST_CHECK((_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_CHECK((!_1)(t) == false);
BOOST_CHECK((!_1)(f) == true);
BOOST_TEST((!_1)(t) == false);
BOOST_TEST((!_1)(f) == true);
// test short circuiting
int i=0;
(false && ++_1)(i);
BOOST_CHECK(i==0);
BOOST_TEST(i==0);
i = 0;
(true && ++_1)(i);
BOOST_CHECK(i==1);
BOOST_TEST(i==1);
i = 0;
(false || ++_1)(i);
BOOST_CHECK(i==1);
BOOST_TEST(i==1);
i = 0;
(true || ++_1)(i);
BOOST_CHECK(i==0);
BOOST_TEST(i==0);
i = 0;
}
void unary_incs_and_decs() {
int i = 0;
BOOST_CHECK(_1++(i) == 0);
BOOST_CHECK(i == 1);
BOOST_TEST(_1++(i) == 0);
BOOST_TEST(i == 1);
i = 0;
BOOST_CHECK(_1--(i) == 0);
BOOST_CHECK(i == -1);
BOOST_TEST(_1--(i) == 0);
BOOST_TEST(i == -1);
i = 0;
BOOST_CHECK((++_1)(i) == 1);
BOOST_CHECK(i == 1);
BOOST_TEST((++_1)(i) == 1);
BOOST_TEST(i == 1);
i = 0;
BOOST_CHECK((--_1)(i) == -1);
BOOST_CHECK(i == -1);
BOOST_TEST((--_1)(i) == -1);
BOOST_TEST(i == -1);
i = 0;
// the result of prefix -- and ++ are lvalues
(++_1)(i) = 10;
BOOST_CHECK(i==10);
BOOST_TEST(i==10);
i = 0;
(--_1)(i) = 10;
BOOST_CHECK(i==10);
BOOST_TEST(i==10);
i = 0;
}
@@ -205,93 +187,77 @@ void compound_operators() {
// normal variable as the left operand
(i += _1)(make_const(1));
BOOST_CHECK(i == 2);
BOOST_TEST(i == 2);
(i -= _1)(make_const(1));
BOOST_CHECK(i == 1);
BOOST_TEST(i == 1);
(i *= _1)(make_const(10));
BOOST_CHECK(i == 10);
BOOST_TEST(i == 10);
(i /= _1)(make_const(2));
BOOST_CHECK(i == 5);
BOOST_TEST(i == 5);
(i %= _1)(make_const(2));
BOOST_CHECK(i == 1);
BOOST_TEST(i == 1);
// lambda expression as a left operand
(_1 += 1)(i);
BOOST_CHECK(i == 2);
BOOST_TEST(i == 2);
(_1 -= 1)(i);
BOOST_CHECK(i == 1);
BOOST_TEST(i == 1);
(_1 *= 10)(i);
BOOST_CHECK(i == 10);
BOOST_TEST(i == 10);
(_1 /= 2)(i);
BOOST_CHECK(i == 5);
BOOST_TEST(i == 5);
(_1 %= 2)(i);
BOOST_CHECK(i == 1);
// lambda expression as a left operand with rvalue on RHS
(_1 += (0 + 1))(i);
BOOST_CHECK(i == 2);
(_1 -= (0 + 1))(i);
BOOST_CHECK(i == 1);
(_1 *= (0 + 10))(i);
BOOST_CHECK(i == 10);
(_1 /= (0 + 2))(i);
BOOST_CHECK(i == 5);
(_1 %= (0 + 2))(i);
BOOST_CHECK(i == 1);
BOOST_TEST(i == 1);
// shifts
unsigned int ui = 2;
(_1 <<= 1)(ui);
BOOST_CHECK(ui==(2 << 1));
BOOST_TEST(ui==(2 << 1));
ui = 2;
(_1 >>= 1)(ui);
BOOST_CHECK(ui==(2 >> 1));
BOOST_TEST(ui==(2 >> 1));
ui = 2;
(ui <<= _1)(make_const(1));
BOOST_CHECK(ui==(2 << 1));
BOOST_TEST(ui==(2 << 1));
ui = 2;
(ui >>= _1)(make_const(1));
BOOST_CHECK(ui==(2 >> 1));
BOOST_TEST(ui==(2 >> 1));
// and, or, xor
ui = 2;
(_1 &= 1)(ui);
BOOST_CHECK(ui==(2 & 1));
BOOST_TEST(ui==(2 & 1));
ui = 2;
(_1 |= 1)(ui);
BOOST_CHECK(ui==(2 | 1));
BOOST_TEST(ui==(2 | 1));
ui = 2;
(_1 ^= 1)(ui);
BOOST_CHECK(ui==(2 ^ 1));
BOOST_TEST(ui==(2 ^ 1));
ui = 2;
(ui &= _1)(make_const(1));
BOOST_CHECK(ui==(2 & 1));
BOOST_TEST(ui==(2 & 1));
ui = 2;
(ui |= _1)(make_const(1));
BOOST_CHECK(ui==(2 | 1));
BOOST_TEST(ui==(2 | 1));
ui = 2;
(ui ^= _1)(make_const(1));
BOOST_CHECK(ui==(2 ^ 1));
BOOST_TEST(ui==(2 ^ 1));
}
@@ -305,24 +271,24 @@ void assignment_and_subscript() {
string s;
(_1 = "one")(s);
BOOST_CHECK(s == string("one"));
BOOST_TEST(s == string("one"));
(var(s) = "two")();
BOOST_CHECK(s == string("two"));
BOOST_TEST(s == string("two"));
BOOST_CHECK((var(s)[_1])(make_const(2)) == 'o');
BOOST_CHECK((_1[2])(s) == 'o');
BOOST_CHECK((_1[_2])(s, make_const(2)) == 'o');
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_CHECK(s == "too");
BOOST_TEST(s == "too");
(_1[1])(s) = 'a';
BOOST_CHECK(s == "tao");
BOOST_TEST(s == "tao");
(_1[_2])(s, make_const(0)) = 'm';
BOOST_CHECK(s == "mao");
BOOST_TEST(s == "mao");
// TODO: tests for vector, set, map, multimap
}
@@ -333,26 +299,16 @@ void address_of_and_dereference() {
A a; int i = 42;
BOOST_CHECK((&_1)(a) == &a);
BOOST_CHECK((*&_1)(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_CHECK(vi[0] == 7);
const std::vector<int>::iterator cit(it);
(*_1 = 8)(cit);
BOOST_CHECK(vi[0] == 8);
BOOST_TEST(vi[0] == 7);
// TODO: Add tests for more complex iterator types
boost::shared_ptr<int> ptr(new int(0));
(*_1 = 7)(ptr);
BOOST_CHECK(*ptr == 7);
const boost::shared_ptr<int> cptr(ptr);
(*_1 = 8)(cptr);
BOOST_CHECK(*ptr == 8);
}
@@ -360,7 +316,7 @@ void address_of_and_dereference() {
void comma() {
int i = 100;
BOOST_CHECK((_1 = 10, 2 * _1)(i) == 20);
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)
@@ -379,32 +335,32 @@ void pointer_arithmetic() {
// non-const array
BOOST_CHECK((*(_1 + 1))(ia) == 2);
BOOST_TEST((*(_1 + 1))(ia) == 2);
// non-const pointer
BOOST_CHECK((*(_1 + 1))(ip) == 2);
BOOST_TEST((*(_1 + 1))(ip) == 2);
BOOST_CHECK((*(_1 - 1))(ia_last) == 3);
BOOST_TEST((*(_1 - 1))(ia_last) == 3);
// const array
BOOST_CHECK((*(_1 + 1))(cia) == 2);
BOOST_TEST((*(_1 + 1))(cia) == 2);
// const pointer
BOOST_CHECK((*(_1 + 1))(cip) == 2);
BOOST_CHECK((*(_1 - 1))(cia_last) == 3);
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_CHECK(ia[2] == 0);
BOOST_CHECK(ia[3] == 0);
BOOST_TEST(ia[2] == 0);
BOOST_TEST(ia[3] == 0);
// pointer - pointer
BOOST_CHECK((_1 - _2)(ia_last, ia) == 3);
BOOST_CHECK((_1 - _2)(cia_last, cia) == 3);
BOOST_CHECK((ia_last - _1)(ia) == 3);
BOOST_CHECK((cia_last - _1)(cia) == 3);
BOOST_CHECK((cia_last - _1)(cip) == 3);
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);
}

View File

@@ -1,18 +1,7 @@
// phoenix_style_control_structures.cpp -- The Boost Lambda Library ------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 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)
//
// For more information, see www.boost.org
// phoenix_style_control_structures.cpp --------------------------------
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#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"
@@ -32,9 +21,11 @@ using namespace boost::lambda;
using namespace std;
// If-else, while, do-while, for statements
///////////////////////////////////////////////////////////////////////////////
//
// If-else, while, do-while, for tatements
//
///////////////////////////////////////////////////////////////////////////////
int test_main(int, char *[]) {
@@ -60,7 +51,7 @@ int test_main(int, char *[]) {
]
);
BOOST_CHECK(sum == 4+5+6+7+8);
BOOST_TEST(sum == 4+5+6+7+8);
int gt = 0, eq = 0, lt = 0;
//////////////////////////////////
@@ -82,9 +73,9 @@ int test_main(int, char *[]) {
]
);
BOOST_CHECK(lt==4);
BOOST_CHECK(eq==1);
BOOST_CHECK(gt==5);
BOOST_TEST(lt==4);
BOOST_TEST(eq==1);
BOOST_TEST(gt==5);
vector<int> t = v;
@@ -101,8 +92,8 @@ int test_main(int, char *[]) {
)
);
BOOST_CHECK(counta == 55);
BOOST_CHECK(countb == 10);
BOOST_TEST(counta == 55);
BOOST_TEST(countb == 10);
v = t;
@@ -120,8 +111,8 @@ int test_main(int, char *[]) {
)
);
BOOST_CHECK(counta == (2+11)*10/2);
BOOST_CHECK(countb == 10);
BOOST_TEST(counta == (2+11)*10/2);
BOOST_TEST(countb == 10);
v = t;
@@ -138,8 +129,8 @@ int test_main(int, char *[]) {
)
);
BOOST_CHECK(counta == (1+10)*10/2);
BOOST_CHECK(countb == 10);
BOOST_TEST(counta == (1+10)*10/2);
BOOST_TEST(countb == 10);
v = t;

View File

@@ -1,314 +0,0 @@
// result_of_tests.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2010 Steven Watanabe
//
// 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)
//
// For more information, see www.boost.org
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_same.hpp>
struct with_result_type {
typedef int result_type;
int operator()() const { return 0; }
int operator()(int) const { return 1; }
int operator()(int, int) const { return 2; }
int operator()(int, int, int) const { return 3; }
int operator()(int, int, int, int) const { return 4; }
int operator()(int, int, int, int, int) const { return 5; }
int operator()(int, int, int, int, int, int) const { return 6; }
int operator()(int, int, int, int, int, int, int) const { return 7; }
int operator()(int, int, int, int, int, int, int, int) const { return 8; }
int operator()(int, int, int, int, int, int, int, int, int) const { return 9; }
};
struct with_result_template_value {
template<class Sig>
struct result;
template<class This>
struct result<This()> {
typedef int type;
};
template<class This, class A1>
struct result<This(A1)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
typedef int type;
};
template<class This, class A1, class A2>
struct result<This(A1, A2)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
typedef int type;
};
template<class This, class A1, class A2, class A3>
struct result<This(A1, A2, A3)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
BOOST_MPL_ASSERT((boost::is_same<A3, int>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4>
struct result<This(A1, A2, A3, A4)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
BOOST_MPL_ASSERT((boost::is_same<A3, int>));
BOOST_MPL_ASSERT((boost::is_same<A4, int>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5>
struct result<This(A1, A2, A3, A4, A5)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
BOOST_MPL_ASSERT((boost::is_same<A3, int>));
BOOST_MPL_ASSERT((boost::is_same<A4, int>));
BOOST_MPL_ASSERT((boost::is_same<A5, int>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6>
struct result<This(A1, A2, A3, A4, A5, A6)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
BOOST_MPL_ASSERT((boost::is_same<A3, int>));
BOOST_MPL_ASSERT((boost::is_same<A4, int>));
BOOST_MPL_ASSERT((boost::is_same<A5, int>));
BOOST_MPL_ASSERT((boost::is_same<A6, int>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
struct result<This(A1, A2, A3, A4, A5, A6, A7)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
BOOST_MPL_ASSERT((boost::is_same<A3, int>));
BOOST_MPL_ASSERT((boost::is_same<A4, int>));
BOOST_MPL_ASSERT((boost::is_same<A5, int>));
BOOST_MPL_ASSERT((boost::is_same<A6, int>));
BOOST_MPL_ASSERT((boost::is_same<A7, int>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
struct result<This(A1, A2, A3, A4, A5, A6, A7, A8)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
BOOST_MPL_ASSERT((boost::is_same<A3, int>));
BOOST_MPL_ASSERT((boost::is_same<A4, int>));
BOOST_MPL_ASSERT((boost::is_same<A5, int>));
BOOST_MPL_ASSERT((boost::is_same<A6, int>));
BOOST_MPL_ASSERT((boost::is_same<A7, int>));
BOOST_MPL_ASSERT((boost::is_same<A8, int>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
struct result<This(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
BOOST_MPL_ASSERT((boost::is_same<A3, int>));
BOOST_MPL_ASSERT((boost::is_same<A4, int>));
BOOST_MPL_ASSERT((boost::is_same<A5, int>));
BOOST_MPL_ASSERT((boost::is_same<A6, int>));
BOOST_MPL_ASSERT((boost::is_same<A7, int>));
BOOST_MPL_ASSERT((boost::is_same<A8, int>));
BOOST_MPL_ASSERT((boost::is_same<A9, int>));
typedef int type;
};
int operator()() const { return 0; }
int operator()(int) const { return 1; }
int operator()(int, int) const { return 2; }
int operator()(int, int, int) const { return 3; }
int operator()(int, int, int, int) const { return 4; }
int operator()(int, int, int, int, int) const { return 5; }
int operator()(int, int, int, int, int, int) const { return 6; }
int operator()(int, int, int, int, int, int, int) const { return 7; }
int operator()(int, int, int, int, int, int, int, int) const { return 8; }
int operator()(int, int, int, int, int, int, int, int, int) const { return 9; }
};
struct with_result_template_reference {
template<class Sig>
struct result;
template<class This>
struct result<This()> {
typedef int type;
};
template<class This, class A1>
struct result<This(A1)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
typedef int type;
};
template<class This, class A1, class A2>
struct result<This(A1, A2)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
typedef int type;
};
template<class This, class A1, class A2, class A3>
struct result<This(A1, A2, A3)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4>
struct result<This(A1, A2, A3, A4)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5>
struct result<This(A1, A2, A3, A4, A5)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6>
struct result<This(A1, A2, A3, A4, A5, A6)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
BOOST_MPL_ASSERT((boost::is_same<A6, int&>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
struct result<This(A1, A2, A3, A4, A5, A6, A7)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
BOOST_MPL_ASSERT((boost::is_same<A6, int&>));
BOOST_MPL_ASSERT((boost::is_same<A7, int&>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
struct result<This(A1, A2, A3, A4, A5, A6, A7, A8)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
BOOST_MPL_ASSERT((boost::is_same<A6, int&>));
BOOST_MPL_ASSERT((boost::is_same<A7, int&>));
BOOST_MPL_ASSERT((boost::is_same<A8, int&>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
struct result<This(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
BOOST_MPL_ASSERT((boost::is_same<A6, int&>));
BOOST_MPL_ASSERT((boost::is_same<A7, int&>));
BOOST_MPL_ASSERT((boost::is_same<A8, int&>));
BOOST_MPL_ASSERT((boost::is_same<A9, int&>));
typedef int type;
};
int operator()() const { return 0; }
int operator()(int) const { return 1; }
int operator()(int, int) const { return 2; }
int operator()(int, int, int) const { return 3; }
int operator()(int, int, int, int) const { return 4; }
int operator()(int, int, int, int, int) const { return 5; }
int operator()(int, int, int, int, int, int) const { return 6; }
int operator()(int, int, int, int, int, int, int) const { return 7; }
int operator()(int, int, int, int, int, int, int, int) const { return 8; }
int operator()(int, int, int, int, int, int, int, int, int) const { return 9; }
};
template<class F>
typename boost::result_of<F()>::type apply0(F f) {
return f();
}
template<class A, class F>
typename boost::result_of<F(A)>::type apply1(F f, A a) {
return f(a);
}
template<class A, class B, class F>
typename boost::result_of<F(A, B)>::type apply2(F f, A a, B b) {
return f(a, b);
}
template<class A, class B, class C, class F>
typename boost::result_of<F(A, B, C)>::type apply3(F f, A a, B b, C c) {
return f(a, b, c);
}
using namespace boost::lambda;
int test_main(int, char *[]) {
BOOST_CHECK(boost::lambda::bind(with_result_type())() == 0);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1)() == 1);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2)() == 2);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3)() == 3);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4)() == 4);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5)() == 5);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6)() == 6);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6, 7)() == 7);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6, 7, 8)() == 8);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6, 7, 8, 9)() == 9);
// Nullary result_of fails
//BOOST_CHECK(boost::lambda::bind(with_result_template_value())() == 0);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1)() == 1);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2)() == 2);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3)() == 3);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4)() == 4);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5)() == 5);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6)() == 6);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6, 7)() == 7);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6, 7, 8)() == 8);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6, 7, 8, 9)() == 9);
int one = 1,
two = 2,
three = 3,
four = 4,
five = 5,
six = 6,
seven = 7,
eight = 8,
nine = 9;
// Nullary result_of fails
//BOOST_CHECK(boost::lambda::bind(with_result_template_reference())() == 0);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one))() == 1);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two))() == 2);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three))() == 3);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four))() == 4);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five))() == 5);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five), var(six))() == 6);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five), var(six), var(seven))() == 7);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five), var(six), var(seven), var(eight))() == 8);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five), var(six), var(seven), var(eight), var(nine))() == 9);
// Check using result_of with lambda functors
BOOST_CHECK(apply0(constant(0)) == 0);
BOOST_CHECK(apply1<int>(_1, one) == 1);
BOOST_CHECK(apply1<int&>(_1, one) == 1);
BOOST_CHECK(apply1<const int&>(_1, one) == 1);
BOOST_CHECK((apply2<int, int>(_1 + _2, one, two) == 3));
BOOST_CHECK((apply2<int&, int&>(_1 + _2, one, two) == 3));
BOOST_CHECK((apply2<const int&, const int&>(_1 + _2, one, two) == 3));
BOOST_CHECK((apply3<int, int, int>(_1 + _2 + _3, one, two, three) == 6));
BOOST_CHECK((apply3<int&, int&, int&>(_1 + _2 + _3, one, two, three) == 6));
BOOST_CHECK((apply3<const int&, const int&, const int&>(_1 + _2 + _3, one, two, three) == 6));
return 0;
}

View File

@@ -1,53 +0,0 @@
// ret_test.cpp - The Boost Lambda Library -----------------------
//
// Copyright (C) 2009 Steven Watanabe
//
// 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)
//
// For more information, see www.boost.org
#include <boost/test/minimal.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_same.hpp>
template<class R, class F>
void test_ret(R r, F f) {
typename F::result_type x = f();
BOOST_MPL_ASSERT((boost::is_same<R, typename F::result_type>));
BOOST_CHECK(x == r);
}
template<class R, class F, class T1>
void test_ret(R r, F f, T1& t1) {
typename F::result_type x = f(t1);
BOOST_MPL_ASSERT((boost::is_same<R, typename F::result_type>));
BOOST_CHECK(x == r);
}
class add_result {
public:
add_result(int i = 0) : value(i) {}
friend bool operator==(const add_result& lhs, const add_result& rhs) {
return(lhs.value == rhs.value);
}
private:
int value;
};
class addable {};
add_result operator+(addable, addable) {
return add_result(7);
}
int test_main(int, char*[]) {
addable test;
test_ret(add_result(7), boost::lambda::ret<add_result>(boost::lambda::_1 + test), test);
test_ret(8.0, boost::lambda::ret<double>(boost::lambda::constant(7) + 1));
return 0;
}

View File

@@ -1,57 +0,0 @@
// rvalue_test - test lambda function objects with rvalue arguments
//
// Copyright (c) 2007 Peter Dimov
//
// 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
#include <boost/lambda/lambda.hpp>
#include <boost/detail/lightweight_test.hpp>
int main()
{
using namespace boost::lambda;
int x = 0;
int const y = 1;
int const z = 2;
BOOST_TEST( _1( x ) == 0 );
BOOST_TEST( _1( y ) == 1 );
BOOST_TEST( _1( 2 ) == 2 );
BOOST_TEST( _2( x, x ) == 0 );
BOOST_TEST( _2( x, y ) == 1 );
BOOST_TEST( _2( x, 2 ) == 2 );
BOOST_TEST( _2( 4, x ) == 0 );
BOOST_TEST( _2( 4, y ) == 1 );
BOOST_TEST( _2( 4, 2 ) == 2 );
(_1 = _2)( x, y );
BOOST_TEST( x == y );
(_1 = _2)( x, 3 );
BOOST_TEST( x == 3 );
(_2 = _1)( z, x );
BOOST_TEST( x == z );
(_2 = _1)( 4, x );
BOOST_TEST( x == 4 );
BOOST_TEST( _3( x, x, x ) == x );
BOOST_TEST( _3( x, x, y ) == y );
BOOST_TEST( _3( x, x, 2 ) == 2 );
BOOST_TEST( _3( x, 5, x ) == x );
BOOST_TEST( _3( x, 5, y ) == y );
BOOST_TEST( _3( x, 5, 2 ) == 2 );
BOOST_TEST( _3( 9, 5, x ) == x );
BOOST_TEST( _3( 9, 5, y ) == y );
BOOST_TEST( _3( 9, 5, 2 ) == 2 );
return boost::report_errors();
}

View File

@@ -1,18 +1,7 @@
// switch_test.cpp -- The Boost Lambda Library --------------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 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)
//
// For more information, see www.boost.org
// switch_test.cpp --------------------------------
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#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"
@@ -63,7 +52,7 @@ void do_switch_no_defaults_tests() {
)
);
BOOST_CHECK(check(w, 0));
BOOST_TEST(check(w, 0));
std::fill_n(w.begin(), 10, 0);
// ---
@@ -75,7 +64,7 @@ void do_switch_no_defaults_tests() {
)
);
BOOST_CHECK(check(w, 1));
BOOST_TEST(check(w, 1));
std::fill_n(w.begin(), 10, 0);
// ---
@@ -88,7 +77,7 @@ void do_switch_no_defaults_tests() {
)
);
BOOST_CHECK(check(w, 2));
BOOST_TEST(check(w, 2));
std::fill_n(w.begin(), 10, 0);
// ---
@@ -102,7 +91,7 @@ void do_switch_no_defaults_tests() {
)
);
BOOST_CHECK(check(w, 3));
BOOST_TEST(check(w, 3));
std::fill_n(w.begin(), 10, 0);
// ---
@@ -117,7 +106,7 @@ void do_switch_no_defaults_tests() {
)
);
BOOST_CHECK(check(w, 4));
BOOST_TEST(check(w, 4));
std::fill_n(w.begin(), 10, 0);
// ---
@@ -133,7 +122,7 @@ void do_switch_no_defaults_tests() {
)
);
BOOST_CHECK(check(w, 5));
BOOST_TEST(check(w, 5));
std::fill_n(w.begin(), 10, 0);
// ---
@@ -150,7 +139,7 @@ void do_switch_no_defaults_tests() {
)
);
BOOST_CHECK(check(w, 6));
BOOST_TEST(check(w, 6));
std::fill_n(w.begin(), 10, 0);
// ---
@@ -168,7 +157,7 @@ void do_switch_no_defaults_tests() {
)
);
BOOST_CHECK(check(w, 7));
BOOST_TEST(check(w, 7));
std::fill_n(w.begin(), 10, 0);
// ---
@@ -187,7 +176,7 @@ void do_switch_no_defaults_tests() {
)
);
BOOST_CHECK(check(w, 8));
BOOST_TEST(check(w, 8));
std::fill_n(w.begin(), 10, 0);
}
@@ -216,8 +205,8 @@ void do_switch_yes_defaults_tests() {
)
);
BOOST_CHECK(check(w, -1));
BOOST_CHECK(default_count == 10);
BOOST_TEST(check(w, -1));
BOOST_TEST(default_count == 10);
std::fill_n(w.begin(), 10, 0);
// ---
@@ -230,8 +219,8 @@ void do_switch_yes_defaults_tests() {
)
);
BOOST_CHECK(check(w, 0));
BOOST_CHECK(default_count == 9);
BOOST_TEST(check(w, 0));
BOOST_TEST(default_count == 9);
std::fill_n(w.begin(), 10, 0);
// ---
@@ -245,8 +234,8 @@ void do_switch_yes_defaults_tests() {
)
);
BOOST_CHECK(check(w, 1));
BOOST_CHECK(default_count == 8);
BOOST_TEST(check(w, 1));
BOOST_TEST(default_count == 8);
std::fill_n(w.begin(), 10, 0);
// ---
@@ -261,8 +250,8 @@ void do_switch_yes_defaults_tests() {
)
);
BOOST_CHECK(check(w, 2));
BOOST_CHECK(default_count == 7);
BOOST_TEST(check(w, 2));
BOOST_TEST(default_count == 7);
std::fill_n(w.begin(), 10, 0);
// ---
@@ -278,8 +267,8 @@ void do_switch_yes_defaults_tests() {
)
);
BOOST_CHECK(check(w, 3));
BOOST_CHECK(default_count == 6);
BOOST_TEST(check(w, 3));
BOOST_TEST(default_count == 6);
std::fill_n(w.begin(), 10, 0);
// ---
@@ -296,8 +285,8 @@ void do_switch_yes_defaults_tests() {
)
);
BOOST_CHECK(check(w, 4));
BOOST_CHECK(default_count == 5);
BOOST_TEST(check(w, 4));
BOOST_TEST(default_count == 5);
std::fill_n(w.begin(), 10, 0);
// ---
@@ -315,8 +304,8 @@ void do_switch_yes_defaults_tests() {
)
);
BOOST_CHECK(check(w, 5));
BOOST_CHECK(default_count == 4);
BOOST_TEST(check(w, 5));
BOOST_TEST(default_count == 4);
std::fill_n(w.begin(), 10, 0);
// ---
@@ -335,8 +324,8 @@ void do_switch_yes_defaults_tests() {
)
);
BOOST_CHECK(check(w, 6));
BOOST_CHECK(default_count == 3);
BOOST_TEST(check(w, 6));
BOOST_TEST(default_count == 3);
std::fill_n(w.begin(), 10, 0);
// ---
@@ -356,8 +345,8 @@ void do_switch_yes_defaults_tests() {
)
);
BOOST_CHECK(check(w, 7));
BOOST_CHECK(default_count == 2);
BOOST_TEST(check(w, 7));
BOOST_TEST(default_count == 2);
std::fill_n(w.begin(), 10, 0);
}