mirror of
https://github.com/boostorg/lambda.git
synced 2026-01-21 17:02:36 +00:00
Compare commits
37 Commits
svn-branch
...
svn-branch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bad57ceece | ||
|
|
ec6cc563b1 | ||
|
|
0196c57a0a | ||
|
|
282825b784 | ||
|
|
b8d328c0fc | ||
|
|
c5704cd6e3 | ||
|
|
6f607b3eef | ||
|
|
8bb8820adb | ||
|
|
89fb84d751 | ||
|
|
be2b0df062 | ||
|
|
666a3eca2d | ||
|
|
95d865285e | ||
|
|
ec38046886 | ||
|
|
c713dc5e0c | ||
|
|
ff04032656 | ||
|
|
6f63b3770f | ||
|
|
22e7b9c779 | ||
|
|
68be6f6563 | ||
|
|
02314ab550 | ||
|
|
9f032a7301 | ||
|
|
da56b773a0 | ||
|
|
cd605ff48d | ||
|
|
641babedf8 | ||
|
|
f9a6b38845 | ||
|
|
846a406b7a | ||
|
|
29794ee654 | ||
|
|
f74aae1241 | ||
|
|
624a204462 | ||
|
|
b635d13d2c | ||
|
|
403d82da66 | ||
|
|
0f29970c8b | ||
|
|
05b9bd64c4 | ||
|
|
e1b36955b7 | ||
|
|
c6030ac58d | ||
|
|
e6edfdf997 | ||
|
|
aabd832db1 | ||
|
|
2aec95e806 |
@@ -5,7 +5,7 @@
|
||||
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="id2808832"></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.
|
||||
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="id2808845"></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.
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
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 Boost Lambda Library"><link rel="next" href="ar01s03.html" title="3. Introduction"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">2. Getting Started</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="index.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ar01s03.html">Next</a></td></tr></table><hr></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="sect:getting_started"></a>2. Getting Started</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2790118"></a>2.1. Installing the library</h3></div></div><p>
|
||||
The library consists of include files only, hence there is no
|
||||
installation procedure. The <tt>boost</tt> include directory
|
||||
must be on the include path.
|
||||
@@ -44,7 +44,7 @@ Cast expressions
|
||||
<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.
|
||||
</p></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2741945"></a>2.2. Conventions used in this document</h3></div></div><p>In most code examples, we omit the namespace prefixes for names in the <tt>std</tt> and <tt>boost::lambda</tt> namespaces.
|
||||
Implicit using declarations
|
||||
<pre class="programlisting">
|
||||
using namespace std;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
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)
|
||||
The Boost Lambda Library"><link rel="previous" href="ar01s02.html" title="2. Getting Started"><link rel="next" href="ar01s04.html" title="4. Using the library"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">3. Introduction</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ar01s02.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ar01s04.html">Next</a></td></tr></table><hr></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="id2741991"></a>3. Introduction</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2741999"></a>3.1. Motivation</h3></div></div><p>The Standard Template Library (STL)
|
||||
[<a href="bi01.html#cit:stepanov:94" title="[STL94]">STL94</a>], now part of the C++ Standard Library [<a href="bi01.html#cit:c++:98" title="[C++98]">C++98</a>], is a generic container and algorithm library.
|
||||
Typically STL algorithms operate on container elements via <span class="emphasis"><i>function objects</i></span>. These function objects are passed as arguments to the algorithms.
|
||||
</p><p>
|
||||
@@ -105,7 +105,7 @@ 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>
|
||||
</p></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2742792"></a>3.2. Introduction to lambda expressions</h3></div></div><p>
|
||||
Lambda expression are common in functional programming languages.
|
||||
Their syntax varies between languages (and between different forms of lambda calculus), but the basic form of a lambda expressions is:
|
||||
|
||||
|
||||
@@ -20,12 +20,12 @@ There are quite a lot of exceptions and special cases, but discussion of them is
|
||||
list<int> v(10);
|
||||
for_each(v.begin(), v.end(), _1 = 1);</pre>
|
||||
|
||||
The expression <tt>_1 = 1</tt> creates a lambda functor which assigns the value <tt>1</tt> to every element in <tt>v</tt>.<sup>[<a name="id2739587" href="#ftn.id2739587">1</a>]</sup>
|
||||
The expression <tt>_1 = 1</tt> creates a lambda functor which assigns the value <tt>1</tt> to every element in <tt>v</tt>.<sup>[<a name="id2739596" href="#ftn.id2739596">1</a>]</sup>
|
||||
</p><p>
|
||||
Next, we create a container of pointers and make them point to the elements in the first container <tt>v</tt>:
|
||||
|
||||
<pre class="programlisting">
|
||||
list<int*> vp(10);
|
||||
vector<int*> vp(10);
|
||||
transform(v.begin(), v.end(), vp.begin(), &_1);</pre>
|
||||
|
||||
The expression <tt>&_1</tt> creates a function object for getting the address of each element in <tt>v</tt>.
|
||||
@@ -122,19 +122,18 @@ 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);
|
||||
(_1 = 2, _1 + i)(i);
|
||||
</pre>
|
||||
|
||||
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 <tt>i</tt> to it.
|
||||
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>.
|
||||
In other words, the lambda expression that is created is
|
||||
<tt>lambda x.(x = 2, x + 1)</tt> rather than
|
||||
<tt>lambda x.(x = 2, x + i)</tt>.
|
||||
|
||||
</p><p>
|
||||
|
||||
@@ -152,12 +151,12 @@ 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>
|
||||
we are creating the lambda expression <tt>lambda x.(x = 2, 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);
|
||||
(_1 = 2, _1 + ref(i))(i);
|
||||
</pre>
|
||||
|
||||
Note that <tt>ref</tt> and <tt>cref</tt> are different
|
||||
@@ -206,7 +205,7 @@ 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>
|
||||
</p></div><div class="footnotes"><br><hr width="100" align="left"><div class="footnote"><p><sup>[<a name="ftn.id2739596" href="#id2739596">1</a>] </sup>
|
||||
Strictly taken, the C++ standard defines <tt>for_each</tt> as a <span class="emphasis"><i>non-modifying sequence operation</i></span>, and the function object passed to <tt>for_each</tt> should not modify its argument.
|
||||
The requirements for the arguments of <tt>for_each</tt> are unnecessary strict, since as long as the iterators are <span class="emphasis"><i>mutable</i></span>, <tt>for_each</tt> accepts a function object that can have side-effects on their argument.
|
||||
Nevertheless, it is straightforward to provide another function template with the functionality of<tt>std::for_each</tt> but more fine-grained requirements for its arguments.
|
||||
|
||||
@@ -77,7 +77,7 @@ For example, the following is a valid lambda expression:
|
||||
<pre class="programlisting">cout << _1, _2[_3] = _1 && false</pre>
|
||||
</p><p>
|
||||
However, there are some restrictions that originate from the C++ operator overloading rules, and some special cases.
|
||||
</p><div class="section"><div class="titlepage"><div><h4 class="title"><a name="id2740636"></a>5.2.1. Operators that cannot be overloaded</h4></div></div><p>
|
||||
</p><div class="section"><div class="titlepage"><div><h4 class="title"><a name="id2740648"></a>5.2.1. Operators that cannot be overloaded</h4></div></div><p>
|
||||
Some operators cannot be overloaded at all (<tt>::</tt>, <tt>.</tt>, <tt>.*</tt>).
|
||||
For some operators, the requirements on return types prevent them to be overloaded to create lambda functors.
|
||||
These operators are <tt>->.</tt>, <tt>-></tt>, <tt>new</tt>, <tt>new[]</tt>, <tt>delete</tt>, <tt>delete[]</tt> and <tt>?:</tt> (the conditional operator).
|
||||
@@ -308,12 +308,32 @@ operator defined, can be used as target functions.
|
||||
|
||||
In general, BLL cannot deduce the return type of an arbitrary function object.
|
||||
|
||||
However, there is a method for giving BLL this capability for a certain
|
||||
However, there are two methods for giving BLL this capability for a certain
|
||||
function object class.
|
||||
|
||||
</p><div class="simplesect"><div class="titlepage"><div><h5 class="title"><a name="id2803238"></a>The sig template</h5></div></div><p>
|
||||
To make BLL aware of the return type(s) of a function object one needs to
|
||||
provide a member template struct
|
||||
</p><div class="simplesect"><div class="titlepage"><div><h5 class="title"><a name="id2803250"></a>The result_type typedef</h5></div></div><p>
|
||||
|
||||
The BLL supports the standard library convention of declaring the return type
|
||||
of a function object with a member typedef named <tt>result_type</tt> in the
|
||||
function object class.
|
||||
|
||||
Here is a simple example:
|
||||
<pre class="programlisting">
|
||||
struct A {
|
||||
typedef B result_type;
|
||||
B operator()(X, Y, Z);
|
||||
};
|
||||
</pre>
|
||||
|
||||
If a function object does not define a <tt>result_type</tt> typedef,
|
||||
the method described below (<tt>sig</tt> template)
|
||||
is attempted to resolve the return type of the
|
||||
function object. If a function object defines both <tt>result_type</tt>
|
||||
and <tt>sig</tt>, <tt>result_type</tt> takes precedence.
|
||||
|
||||
</p></div><div class="simplesect"><div class="titlepage"><div><h5 class="title"><a name="id2803321"></a>The sig template</h5></div></div><p>
|
||||
Another mechanism that make BLL aware of the return type(s) of a function object is defining
|
||||
member template struct
|
||||
<tt>sig<Args></tt> with a typedef
|
||||
<tt>type</tt> that specifies the return type.
|
||||
|
||||
@@ -332,9 +352,7 @@ 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 the Standard Library
|
||||
convention for defining the return type of a function
|
||||
object with the <tt>return_type</tt> typedef.
|
||||
This may seem overly complex compared to defining the <tt>result_type</tt> typedef.
|
||||
Howver, there are two significant restrictions with using just a simple
|
||||
typedef to express the return type:
|
||||
<div class="orderedlist"><ol type="1"><li><p>
|
||||
@@ -396,25 +414,7 @@ for tools that can aid in these tasks.
|
||||
The <tt>sig</tt> templates are a refined version of a similar
|
||||
mechanism first introduced in the FC++ library
|
||||
[<a href="bi01.html#cit:fc++" title="[fc++]">fc++</a>].
|
||||
</p></div><p>
|
||||
Earlier versions of the library supported the Standard Library convention
|
||||
as the default, and required special actions to make the library recognize
|
||||
the <tt>sig</tt> 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 <tt>std_functor</tt>
|
||||
wrapper, that gives the function object a <tt>sig</tt>
|
||||
template based on the <tt>result_type</tt> typedef.
|
||||
For example:
|
||||
|
||||
<pre class="programlisting">
|
||||
int i = 1;
|
||||
bind(plus<int>(), _1, 1)(i); // error, no sig template
|
||||
bind(std_functor(plus<int>()), _1, 1)(i); // ok
|
||||
</pre>
|
||||
|
||||
</p></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="sect:overriding_deduced_return_type"></a>5.4. Overriding the deduced return type</h3></div></div><p>
|
||||
</p></div></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="sect:overriding_deduced_return_type"></a>5.4. Overriding the deduced return type</h3></div></div><p>
|
||||
The return type deduction system may not be able to deduce the return types of some user defined operators or bind expressions with class objects.
|
||||
|
||||
A special lambda expression type is provided for stating the return type explicitly and overriding the deduction system.
|
||||
@@ -533,7 +533,7 @@ By using <tt>var</tt> to make <tt>index</tt> a lambda expression, we get the des
|
||||
In sum, <tt>var(x)</tt> creates a nullary lambda functor,
|
||||
which stores a reference to the variable <tt>x</tt>.
|
||||
When the lambda functor is invoked, a reference to <tt>x</tt> is returned.
|
||||
</p><div class="simplesect"><div class="titlepage"><div><h4 class="title"><a name="id2804083"></a>Naming delayed constants and variables</h4></div></div><p>
|
||||
</p><div class="simplesect"><div class="titlepage"><div><h4 class="title"><a name="id2804115"></a>Naming delayed constants and variables</h4></div></div><p>
|
||||
It is possible to predefine and name a delayed variable or constant outside a lambda expression.
|
||||
The templates <tt>var_type</tt>, <tt>constant_type</tt>
|
||||
and <tt>constant_ref_type</tt> serve for this purpose.
|
||||
@@ -562,7 +562,7 @@ Here is an example of naming a delayed constant:
|
||||
constant_type<char>::type space(constant(' '));
|
||||
for_each(a.begin(),a.end(), cout << space << _1);
|
||||
</pre>
|
||||
</p></div><div class="simplesect"><div class="titlepage"><div><h4 class="title"><a name="id2804207"></a>About assignment and subscript operators</h4></div></div><p>
|
||||
</p></div><div class="simplesect"><div class="titlepage"><div><h4 class="title"><a name="id2804238"></a>About assignment and subscript operators</h4></div></div><p>
|
||||
As described in <a href="ar01s05.html#sect:assignment_and_subscript" title="5.2.2. Assignment and subscript operators">Section 5.2.2</a>, assignment and subscripting operators are always defined as member functions.
|
||||
This means, that for expressions of the form
|
||||
<tt>x = y</tt> or <tt>x[y]</tt> to be interpreted as lambda expressions, the left-hand operand <tt>x</tt> must be a lambda expression.
|
||||
@@ -635,13 +635,7 @@ for_each(a, a+5,
|
||||
The BLL supports an alternative syntax for control expressions, suggested
|
||||
by Joel de Guzmann.
|
||||
By overloading the <tt>operator[]</tt> we can
|
||||
get a closer resemblance with the built-in control structures.
|
||||
For example, using this syntax the <tt>if_then</tt> example above
|
||||
can be written as:
|
||||
<pre class="programlisting">
|
||||
for_each(a.begin(), a.end(),
|
||||
if(_1 % 2 == 0)[ cout << _1 ])
|
||||
</pre>
|
||||
get a closer resemblance with the built-in control structures:
|
||||
|
||||
<pre class="programlisting">
|
||||
if_(condition)[then_part]
|
||||
@@ -651,6 +645,13 @@ do_[body].while_(condition)
|
||||
for_(init, condition, increment)[body]
|
||||
</pre>
|
||||
|
||||
For example, using this syntax the <tt>if_then</tt> example above
|
||||
can be written as:
|
||||
<pre class="programlisting">
|
||||
for_each(a.begin(), a.end(),
|
||||
if_(_1 % 2 == 0)[ cout << _1 ])
|
||||
</pre>
|
||||
|
||||
As more experience is gained, we may end up deprecating one or the other
|
||||
of these syntaces.
|
||||
|
||||
@@ -849,7 +850,7 @@ objects related to creating and destroying objects,
|
||||
showing the expression to create and call the function object,
|
||||
and the effect of evaluating that expression.
|
||||
|
||||
</p><div class="table"><p><a name="table:constructor_destructor_fos"></a><b>Table 1. Construction and destruction related function objects.</b></p><table summary="Construction and destruction related function objects." border="1"><colgroup><col><col></colgroup><thead><tr><th>Function object call</th><th>Wrapped expression</th></tr></thead><tbody><tr><td><tt>constructor<T>()(<i><tt>arg_list</tt></i>)</tt></td><td>T(<i><tt>arg_list</tt></i>)</td></tr><tr><td><tt>destructor()(a)</tt></td><td><tt>a.~A()</tt>, where <tt>a</tt> is of type <tt>A</tt></td></tr><tr><td><tt>destructor()(pa)</tt></td><td><tt>pa.->A()</tt>, where <tt>pa</tt> is of type <tt>A*</tt></td></tr><tr><td><tt>new_ptr<T>()(<i><tt>arg_list</tt></i>)</tt></td><td><tt>new T(<i><tt>arg_list</tt></i>)</tt></td></tr><tr><td><tt>new_array<T>()(sz)</tt></td><td><tt>new T[sz]</tt></td></tr><tr><td><tt>delete_ptr()(p)</tt></td><td><tt>delete p</tt></td></tr><tr><td><tt>delete_array()(p)</tt></td><td><tt>delete p[]</tt></td></tr></tbody></table></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2805476"></a>5.9. Special lambda expressions</h3></div></div><div class="section"><div class="titlepage"><div><h4 class="title"><a name="id2805483"></a>5.9.1. Preventing argument substitution</h4></div></div><p>
|
||||
</p><div class="table"><p><a name="table:constructor_destructor_fos"></a><b>Table 1. Construction and destruction related function objects.</b></p><table summary="Construction and destruction related function objects." border="1"><colgroup><col><col></colgroup><thead><tr><th>Function object call</th><th>Wrapped expression</th></tr></thead><tbody><tr><td><tt>constructor<T>()(<i><tt>arg_list</tt></i>)</tt></td><td>T(<i><tt>arg_list</tt></i>)</td></tr><tr><td><tt>destructor()(a)</tt></td><td><tt>a.~A()</tt>, where <tt>a</tt> is of type <tt>A</tt></td></tr><tr><td><tt>destructor()(pa)</tt></td><td><tt>pa->~A()</tt>, where <tt>pa</tt> is of type <tt>A*</tt></td></tr><tr><td><tt>new_ptr<T>()(<i><tt>arg_list</tt></i>)</tt></td><td><tt>new T(<i><tt>arg_list</tt></i>)</tt></td></tr><tr><td><tt>new_array<T>()(sz)</tt></td><td><tt>new T[sz]</tt></td></tr><tr><td><tt>delete_ptr()(p)</tt></td><td><tt>delete p</tt></td></tr><tr><td><tt>delete_array()(p)</tt></td><td><tt>delete p[]</tt></td></tr></tbody></table></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2805507"></a>5.9. Special lambda expressions</h3></div></div><div class="section"><div class="titlepage"><div><h4 class="title"><a name="id2805514"></a>5.9.1. Preventing argument substitution</h4></div></div><p>
|
||||
When a lambda functor is called, the default behavior is to substitute
|
||||
the actual arguments for the placeholders within all subexpressions.
|
||||
|
||||
@@ -975,7 +976,7 @@ int nested(const F& f) {
|
||||
}
|
||||
</pre>
|
||||
|
||||
</p></div><div class="section"><div class="titlepage"><div><h5 class="title"><a name="id2805743"></a>5.9.1.2. Protect</h5></div></div><p>
|
||||
</p></div><div class="section"><div class="titlepage"><div><h5 class="title"><a name="id2805774"></a>5.9.1.2. Protect</h5></div></div><p>
|
||||
The <tt>protect</tt> function is related to unlambda.
|
||||
|
||||
It is also used to prevent the argument substitution taking place,
|
||||
@@ -1080,7 +1081,7 @@ since calls to sub lambda functors are made inside the BLL,
|
||||
and are not affected by the non-const rvalue problem.
|
||||
</p></li></ol></div>
|
||||
|
||||
</p></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2806049"></a>5.10. Casts, sizeof and typeid</h3></div></div><div class="section"><div class="titlepage"><div><h4 class="title"><a name="sect:cast_expressions"></a>5.10.1.
|
||||
</p></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2806080"></a>5.10. Casts, sizeof and typeid</h3></div></div><div class="section"><div class="titlepage"><div><h4 class="title"><a name="sect:cast_expressions"></a>5.10.1.
|
||||
Cast expressions
|
||||
</h4></div></div><p>
|
||||
The BLL defines its counterparts for the four cast expressions
|
||||
@@ -1109,7 +1110,7 @@ int count = 0;
|
||||
for_each(a.begin(), a.end(),
|
||||
if_then(ll_dynamic_cast<derived*>(_1), ++var(count)));
|
||||
</pre>
|
||||
</p></div><div class="section"><div class="titlepage"><div><h4 class="title"><a name="id2806151"></a>5.10.2. Sizeof and typeid</h4></div></div><p>
|
||||
</p></div><div class="section"><div class="titlepage"><div><h4 class="title"><a name="id2806181"></a>5.10.2. Sizeof and typeid</h4></div></div><p>
|
||||
The BLL counterparts for these expressions are named
|
||||
<tt>ll_sizeof</tt> and <tt>ll_typeid</tt>.
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
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="id2807558"></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
|
||||
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="id2807588"></a>7. Practical considerations</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2807595"></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.
|
||||
|
||||
@@ -75,7 +75,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 experiensed
|
||||
Although the above tests do not include such an expression, we have experienced
|
||||
this for some seemingly simple expressions.
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ The running times are expressed in arbitrary units." border="1"><colgroup><col><
|
||||
</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="id2808057"></a>7.2. About compiling</h3></div></div><p>The BLL uses templates rather heavily, performing numerous recursive instantiations of the same templates.
|
||||
</p></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2808087"></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.
|
||||
@@ -105,13 +105,13 @@ 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.
|
||||
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.
|
||||
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>
|
||||
</p></li></ul></div></p></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2808149"></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
|
||||
@@ -120,7 +120,7 @@ The BLL works with the following compilers, that is, the compilers are capable o
|
||||
)
|
||||
|
||||
</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:
|
||||
</p><div class="section"><div class="titlepage"><div><h4 class="title"><a name="id2808188"></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.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
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="id2808510"></a>8.1. Boost Function</h3></div></div><p>Sometimes it is convenient to store lambda functors in variables.
|
||||
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="id2808533"></a>8. Relation to other Boost libraries</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2808540"></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.
|
||||
@@ -13,14 +13,14 @@ lambda functors; and these wrappers have types that are easy to type out.
|
||||
For example:
|
||||
|
||||
<pre class="programlisting">
|
||||
boost::function<int, int, int> f = _1 + _2;
|
||||
boost::function<int&, int&> g = unlambda(_1 += 10);
|
||||
boost::function<int(int, int)> f = _1 + _2;
|
||||
boost::function<int&(int&)> g = (_1 += 10);
|
||||
int i = 1, j = 2;
|
||||
f(i); // returns 3
|
||||
g(i); // sets i to = 11;
|
||||
f(i, j); // returns 3
|
||||
g(i); // sets i to = 11;
|
||||
</pre>
|
||||
|
||||
The return and parameter types of the wrapped function object must be written explicilty as template arguments to the wrapper template <tt>boost::function</tt>; even when lambda functors, which otherwise have generic parameters, are wrapped.
|
||||
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>
|
||||
@@ -38,13 +38,13 @@ For example:
|
||||
<pre class="programlisting">
|
||||
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;
|
||||
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="id2808614"></a>8.2. Boost Bind</h3></div></div><p>
|
||||
</p></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2808644"></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.
|
||||
@@ -63,7 +63,7 @@ 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>
|
||||
</p><div class="section"><div class="titlepage"><div><h4 class="title"><a name="id2808709"></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,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
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 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="id2808824"></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.
|
||||
|
||||
@@ -5,12 +5,21 @@
|
||||
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="id2808984" class="bibliography"><div class="titlepage"><div><h2 class="title"><a name="id2808984"></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">
|
||||
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="id2808997" class="bibliography"><div class="titlepage"><div><h2 class="title"><a name="id2808997"></a>Bibliography</h2></div></div><div class="biblioentry"><a name="cit:stepanov:94"></a><p>[STL94] <span class="authorgroup">A. A. Stepanov and M. Lee. </span><span class="title"><I>The Standard Template Library</I>. </span><span class="orgname">Hewlett-Packard Laboratories. </span><span class="pubdate">1994. </span><span class="bibliomisc">
|
||||
<a href="http://www.hpl.hp.com/techreports" target="_top">www.hpl.hp.com/techreports</a>
|
||||
. </span></p></div><div class="biblioentry"><a name="cit:sgi:02"></a><p>[SGI02] <span class="title"><I>The SGI Standard Template Library</I>. </span><span class="pubdate">2002. </span><span class="bibliomisc"><a href="http://www.sgi.com/tech/stl/" target="_top">www.sgi.com/tech/stl/</a>. </span></p></div><div class="biblioentry"><a name="cit:c++:98"></a><p>[C++98] <span class="title"><I>International Standard, Programming Languages – C++</I>. </span><span class="subtitle">ISO/IEC:14882. </span><span class="pubdate">1998. </span></p></div><div class="biblioentry"><a name="cit:jarvi:99"></a><p>[Jär99] <span class="articleinfo">
|
||||
<span class="author">Jaakko Järvi. </span>
|
||||
<span class="title"><I>C++ Function Object Binders Made Easy</I>. </span>
|
||||
. </span><span class="title"><I>Lecture Notes in Computer Science</I>. </span><span class="volumenum">1977. </span><span class="publishername">Springer. </span><span class="pubdate">2000. </span></p></div><div class="biblioentry"><a name="cit:jarvi:00"></a><p>[Jär00] <span class="author">Jaakko Järvi. </span><span class="author">Gary Powell. </span><span class="title"><I>The Lambda Library : Lambda Abstraction in C++</I>. </span><span class="orgname">Turku Centre for Computer Science. </span><span class="bibliomisc">Technical Report . </span><span class="issuenum">378. </span><span class="pubdate">2000. </span><span class="bibliomisc"><a href="http://www.tucs.fi/Publications/techreports/TR378.php" target="_top">www.tucs.fi/publications</a>. </span></p></div><div class="biblioentry"><a name="cit:jarvi:01"></a><p>[Jär01] <span class="author">Jaakko Järvi. </span><span class="author">Gary Powell. </span><span class="title"><I>The Lambda Library : Lambda Abstraction in C++</I>. </span><span class="confgroup"><span class="conftitle">Second Workshop on C++ Template Programming. </span><span class="address">Tampa Bay, OOPSLA'01. </span>. </span><span class="pubdate">2001. </span><span class="bibliomisc"><a href="http://www.oonumerics.org/tmpw01/" target="_top">www.oonumerics.org/tmpw01/</a>. </span></p></div><div class="biblioentry"><a name="cit:boost::tuple"></a><p>[tuple] <span class="title"><I>The Boost Tuple Library</I>. </span><span class="bibliomisc"><a href="http://www.boost.org/libs/tuple/doc/tuple_users_guide.html" target="_top">www.boost.org/libs/tuple/doc/tuple_users_guide.html</a>
|
||||
. </span><span class="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:jarvi:03"></a><p>[Jär03] <span class="articleinfo">
|
||||
|
||||
<span class="author">Jaakko Järvi. </span>
|
||||
|
||||
<span class="author">Gary Powell. </span>
|
||||
|
||||
<span class="author">Andrew Lumsdaine. </span>
|
||||
<span class="title"><I>The Lambda Library : unnamed functions in C++</I>. </span>
|
||||
|
||||
. </span><span class="title"><I>Software - Practice and Expreience</I>. </span><span class="volumenum">33:259-291. </span><span class="pubdate">2003. </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>
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
generated
|
||||
- lambda_doc_chunks.xsl loads the stylesheets that generate a separate
|
||||
html-file for each section
|
||||
- lambda_doc.html loads stylesheets that generate one big html-file
|
||||
- lambda_doc.xsl loads stylesheets that generate one big html-file
|
||||
(you need to edit the paths in these files to make them work)
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
|
||||
<!-- -->
|
||||
|
||||
<ulink url="lambda_docs_as_one_file.html">Documentation as a one big HTML-file</ulink>
|
||||
|
||||
<section id="introduction">
|
||||
|
||||
@@ -444,7 +445,7 @@ Nevertheless, it is straightforward to provide another function template with th
|
||||
Next, we create a container of pointers and make them point to the elements in the first container <literal>v</literal>:
|
||||
|
||||
<programlisting>
|
||||
<![CDATA[list<int*> vp(10);
|
||||
<![CDATA[vector<int*> vp(10);
|
||||
transform(v.begin(), v.end(), vp.begin(), &_1);]]></programlisting>
|
||||
|
||||
The expression <literal><![CDATA[&_1]]></literal> creates a function object for getting the address of each element in <literal>v</literal>.
|
||||
@@ -587,19 +588,18 @@ 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 + i)(i = 2);
|
||||
(_1 = 2, _1 + i)(i);
|
||||
</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 <literal>_1 + i</literal> creates
|
||||
a lambda function <literal>lambda x.x+1</literal> rather than
|
||||
<literal>lambda x.x+i</literal>.
|
||||
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>.
|
||||
|
||||
</para>
|
||||
|
||||
@@ -623,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+i</literal>
|
||||
we are creating the lambda expression <literal>lambda x.(x = 2, x + i)</literal>
|
||||
and the value of the expression in the last line will be 4:
|
||||
|
||||
<programlisting>
|
||||
i = 1;
|
||||
(_1 + ref(i))(i = 2);
|
||||
(_1 = 2, _1 + ref(i))(i);
|
||||
</programlisting>
|
||||
|
||||
Note that <literal>ref</literal> and <literal>cref</literal> are different
|
||||
@@ -1156,18 +1156,46 @@ operator defined, can be used as target functions.
|
||||
|
||||
In general, BLL cannot deduce the return type of an arbitrary function object.
|
||||
|
||||
However, there is a method for giving BLL this capability for a certain
|
||||
However, there are two methods 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>
|
||||
To make BLL aware of the return type(s) of a function object one needs to
|
||||
provide a member template struct
|
||||
Another mechanism that make BLL aware of the return type(s) of a function object is defining
|
||||
member template struct
|
||||
<literal><![CDATA[sig<Args>]]></literal> with a typedef
|
||||
<literal>type</literal> that specifies the return type.
|
||||
|
||||
@@ -1186,9 +1214,7 @@ 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 the Standard Library
|
||||
convention for defining the return type of a function
|
||||
object with the <literal>return_type</literal> typedef.
|
||||
This may seem overly complex compared to defining the <literal>result_type</literal> typedef.
|
||||
Howver, there are two significant restrictions with using just a simple
|
||||
typedef to express the return type:
|
||||
<orderedlist>
|
||||
@@ -1263,27 +1289,6 @@ 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>
|
||||
|
||||
|
||||
@@ -1578,13 +1583,7 @@ for_each(a, a+5,
|
||||
The BLL supports an alternative syntax for control expressions, suggested
|
||||
by Joel de Guzmann.
|
||||
By overloading the <literal>operator[]</literal> we can
|
||||
get a closer resemblance with the built-in control structures.
|
||||
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 ])]]>
|
||||
</programlisting>
|
||||
get a closer resemblance with the built-in control structures:
|
||||
|
||||
<programlisting>
|
||||
<![CDATA[if_(condition)[then_part]
|
||||
@@ -1594,6 +1593,13 @@ do_[body].while_(condition)
|
||||
for_(init, condition, increment)[body]]]>
|
||||
</programlisting>
|
||||
|
||||
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 ])]]>
|
||||
</programlisting>
|
||||
|
||||
As more experience is gained, we may end up deprecating one or the other
|
||||
of these syntaces.
|
||||
|
||||
@@ -1856,7 +1862,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<T>()(<parameter>arg_list</parameter>)</literal></entry>
|
||||
@@ -2719,7 +2725,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 experiensed
|
||||
Although the above tests do not include such an expression, we have experienced
|
||||
this for some seemingly simple expressions.
|
||||
|
||||
|
||||
@@ -2873,7 +2879,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 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.
|
||||
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.
|
||||
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>
|
||||
@@ -3029,14 +3035,14 @@ lambda functors; and these wrappers have types that are easy to type out.
|
||||
For example:
|
||||
|
||||
<programlisting>
|
||||
<![CDATA[boost::function<int, int, int> f = _1 + _2;
|
||||
boost::function<int&, int&> g = unlambda(_1 += 10);
|
||||
<![CDATA[boost::function<int(int, int)> f = _1 + _2;
|
||||
boost::function<int&(int&)> g = (_1 += 10);
|
||||
int i = 1, j = 2;
|
||||
f(i); // returns 3
|
||||
g(i); // sets i to = 11;]]>
|
||||
f(i, j); // returns 3
|
||||
g(i); // sets i to = 11;]]>
|
||||
</programlisting>
|
||||
|
||||
The return and parameter types of the wrapped function object must be written explicilty as template arguments to the wrapper template <literal>boost::function</literal>; even when lambda functors, which otherwise have generic parameters, are wrapped.
|
||||
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.
|
||||
Wrapping a function object with <literal>boost::function</literal> introduces a performance cost comparable to virtual function dispatch, though virtual functions are not actually used.
|
||||
|
||||
Note that storing lambda functors inside <literal>boost::function</literal>
|
||||
@@ -3054,7 +3060,7 @@ For example:
|
||||
<programlisting>
|
||||
<![CDATA[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;
|
||||
delete sum;
|
||||
counter(3); // error, *sum does not exist anymore]]>
|
||||
@@ -3348,6 +3354,37 @@ 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>
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
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#id2808057">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#id2808510">Boost Function</a></dt><dt>8.2. <a href="ar01s08.html#id2808614">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">
|
||||
</p></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt>1. <a href="index.html#introduction">In a nutshell</a></dt><dt>2. <a href="ar01s02.html">Getting Started</a></dt><dd><dl><dt>2.1. <a href="ar01s02.html#id2790118">Installing the library</a></dt><dt>2.2. <a href="ar01s02.html#id2741945">Conventions used in this document</a></dt></dl></dd><dt>3. <a href="ar01s03.html">Introduction</a></dt><dd><dl><dt>3.1. <a href="ar01s03.html#id2741999">Motivation</a></dt><dt>3.2. <a href="ar01s03.html#id2742792">Introduction to lambda expressions</a></dt></dl></dd><dt>4. <a href="ar01s04.html">Using the library</a></dt><dd><dl><dt>4.1. <a href="ar01s04.html#sect:introductory_examples">Introductory Examples</a></dt><dt>4.2. <a href="ar01s04.html#sect:parameter_and_return_types">Parameter and return types of lambda functors</a></dt><dt>4.3. <a href="ar01s04.html#sect:actual_arguments_to_lambda_functors">About actual arguments to lambda functors</a></dt><dt>4.4. <a href="ar01s04.html#sect:storing_bound_arguments">Storing bound arguments in lambda functions</a></dt></dl></dd><dt>5. <a href="ar01s05.html">Lambda expressions in details</a></dt><dd><dl><dt>5.1. <a href="ar01s05.html#sect:placeholders">Placeholders</a></dt><dt>5.2. <a href="ar01s05.html#sect:operator_expressions">Operator expressions</a></dt><dt>5.3. <a href="ar01s05.html#sect:bind_expressions">Bind expressions</a></dt><dt>5.4. <a href="ar01s05.html#sect:overriding_deduced_return_type">Overriding the deduced return type</a></dt><dt>5.5. <a href="ar01s05.html#sect:delaying_constants_and_variables">Delaying constants and variables</a></dt><dt>5.6. <a href="ar01s05.html#sect:lambda_expressions_for_control_structures">Lambda expressions for control structures</a></dt><dt>5.7. <a href="ar01s05.html#sect:exceptions">Exceptions</a></dt><dt>5.8. <a href="ar01s05.html#sect:construction_and_destruction">Construction and destruction</a></dt><dt>5.9. <a href="ar01s05.html#id2805507">Special lambda expressions</a></dt><dt>5.10. <a href="ar01s05.html#id2806080">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#id2807595">Performance</a></dt><dt>7.2. <a href="ar01s07.html#id2808087">About compiling</a></dt><dt>7.3. <a href="ar01s07.html#id2808149">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#id2808540">Boost Function</a></dt><dt>8.2. <a href="ar01s08.html#id2808644">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>
|
||||
</a></dt></dl></dd><dt><a href="bi01.html">Bibliography</a></dt></dl></div><a href="lambda_docs_as_one_file.html" target="_top">Documentation as a one big HTML-file</a><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="introduction"></a>1. In a nutshell</h2></div></div><p>
|
||||
|
||||
The Boost Lambda Library (BLL in the sequel) is a C++ template
|
||||
library, which implements form of <span class="emphasis"><i>lambda abstractions</i></span> for C++.
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
<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"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="article"><div class="titlepage"><div><h1 class="title"><a name="id2732401"></a>
|
||||
The Boost Lambda Library</title><meta name="generator" content="DocBook XSL Stylesheets V1.48"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="article"><div class="titlepage"><div><h1 class="title"><a name="id2732402"></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="#introduction">In a nutshell</a></dt><dt>2. <a href="#sect:getting_started">Getting Started</a></dt><dd><dl><dt>2.1. <a href="#id2779428">Installing the library</a></dt><dt>2.2. <a href="#id2733541">Conventions used in this document</a></dt></dl></dd><dt>3. <a href="#id2733588">Introduction</a></dt><dd><dl><dt>3.1. <a href="#id2733595">Motivation</a></dt><dt>3.2. <a href="#id2733932">Introduction to lambda expressions</a></dt></dl></dd><dt>4. <a href="#sect:using_library">Using the library</a></dt><dd><dl><dt>4.1. <a href="#sect:introductory_examples">Introductory Examples</a></dt><dt>4.2. <a href="#sect:parameter_and_return_types">Parameter and return types of lambda functors</a></dt><dt>4.3. <a href="#sect:actual_arguments_to_lambda_functors">About actual arguments to lambda functors</a></dt><dt>4.4. <a href="#sect:storing_bound_arguments">Storing bound arguments in lambda functions</a></dt></dl></dd><dt>5. <a href="#sect:lambda_expressions_in_details">Lambda expressions in details</a></dt><dd><dl><dt>5.1. <a href="#sect:placeholders">Placeholders</a></dt><dt>5.2. <a href="#sect:operator_expressions">Operator expressions</a></dt><dt>5.3. <a href="#sect:bind_expressions">Bind expressions</a></dt><dt>5.4. <a href="#sect:overriding_deduced_return_type">Overriding the deduced return type</a></dt><dt>5.5. <a href="#sect:delaying_constants_and_variables">Delaying constants and variables</a></dt><dt>5.6. <a href="#sect:lambda_expressions_for_control_structures">Lambda expressions for control structures</a></dt><dt>5.7. <a href="#sect:exceptions">Exceptions</a></dt><dt>5.8. <a href="#sect:construction_and_destruction">Construction and destruction</a></dt><dt>5.9. <a href="#id2794800">Special lambda expressions</a></dt><dt>5.10. <a href="#id2795373">Casts, sizeof and typeid</a></dt><dt>5.11. <a href="#sect:nested_stl_algorithms">Nesting STL algorithm invocations</a></dt></dl></dd><dt>6. <a href="#sect:extending_return_type_system">Extending return type deduction system</a></dt><dt>7. <a href="#id2796882">Practical considerations</a></dt><dd><dl><dt>7.1. <a href="#id2796888">Performance</a></dt><dt>7.2. <a href="#id2797381">About compiling</a></dt><dt>7.3. <a href="#id2797442">Portability</a></dt></dl></dd><dt>8. <a href="#id2797826">Relation to other Boost libraries</a></dt><dd><dl><dt>8.1. <a href="#id2797834">Boost Function</a></dt><dt>8.2. <a href="#id2797938">Boost Bind</a></dt></dl></dd><dt>9. <a href="#id2798134">Contributors</a></dt><dt>A. <a href="#id2798156">Rationale for some of the design decisions</a></dt><dd><dl><dt>1. <a href="#sect:why_weak_arity">
|
||||
</p></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt>1. <a href="#introduction">In a nutshell</a></dt><dt>2. <a href="#sect:getting_started">Getting Started</a></dt><dd><dl><dt>2.1. <a href="#id2779436">Installing the library</a></dt><dt>2.2. <a href="#id2733553">Conventions used in this document</a></dt></dl></dd><dt>3. <a href="#id2733600">Introduction</a></dt><dd><dl><dt>3.1. <a href="#id2733607">Motivation</a></dt><dt>3.2. <a href="#id2733935">Introduction to lambda expressions</a></dt></dl></dd><dt>4. <a href="#sect:using_library">Using the library</a></dt><dd><dl><dt>4.1. <a href="#sect:introductory_examples">Introductory Examples</a></dt><dt>4.2. <a href="#sect:parameter_and_return_types">Parameter and return types of lambda functors</a></dt><dt>4.3. <a href="#sect:actual_arguments_to_lambda_functors">About actual arguments to lambda functors</a></dt><dt>4.4. <a href="#sect:storing_bound_arguments">Storing bound arguments in lambda functions</a></dt></dl></dd><dt>5. <a href="#sect:lambda_expressions_in_details">Lambda expressions in details</a></dt><dd><dl><dt>5.1. <a href="#sect:placeholders">Placeholders</a></dt><dt>5.2. <a href="#sect:operator_expressions">Operator expressions</a></dt><dt>5.3. <a href="#sect:bind_expressions">Bind expressions</a></dt><dt>5.4. <a href="#sect:overriding_deduced_return_type">Overriding the deduced return type</a></dt><dt>5.5. <a href="#sect:delaying_constants_and_variables">Delaying constants and variables</a></dt><dt>5.6. <a href="#sect:lambda_expressions_for_control_structures">Lambda expressions for control structures</a></dt><dt>5.7. <a href="#sect:exceptions">Exceptions</a></dt><dt>5.8. <a href="#sect:construction_and_destruction">Construction and destruction</a></dt><dt>5.9. <a href="#id2794832">Special lambda expressions</a></dt><dt>5.10. <a href="#id2795404">Casts, sizeof and typeid</a></dt><dt>5.11. <a href="#sect:nested_stl_algorithms">Nesting STL algorithm invocations</a></dt></dl></dd><dt>6. <a href="#sect:extending_return_type_system">Extending return type deduction system</a></dt><dt>7. <a href="#id2796913">Practical considerations</a></dt><dd><dl><dt>7.1. <a href="#id2796919">Performance</a></dt><dt>7.2. <a href="#id2797412">About compiling</a></dt><dt>7.3. <a href="#id2797473">Portability</a></dt></dl></dd><dt>8. <a href="#id2797857">Relation to other Boost libraries</a></dt><dd><dl><dt>8.1. <a href="#id2797865">Boost Function</a></dt><dt>8.2. <a href="#id2797969">Boost Bind</a></dt></dl></dd><dt>9. <a href="#id2798148">Contributors</a></dt><dt>A. <a href="#id2798170">Rationale for some of the design decisions</a></dt><dd><dl><dt>1. <a href="#sect:why_weak_arity">
|
||||
Lambda functor arity
|
||||
</a></dt></dl></dd><dt><a href="#id2798308">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>
|
||||
</a></dt></dl></dd><dt><a href="#id2798322">Bibliography</a></dt></dl></div><a href="lambda_docs_as_one_file.html" target="_top">Documentation as a one big HTML-file</a><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="introduction"></a>1. In a nutshell</h2></div></div><p>
|
||||
|
||||
The Boost Lambda Library (BLL in the sequel) is a C++ template
|
||||
library, which implements form of <span class="emphasis"><i>lambda abstractions</i></span> for C++.
|
||||
@@ -29,7 +29,7 @@ In explaining what the library is about, a line of code says more than a thousan
|
||||
called with an element of <tt>a</tt> as the actual argument.
|
||||
This actual argument is substituted for the placeholder, and the ‘body’ of the function is evaluated.
|
||||
</p><p>The essence of BLL is letting you define small unnamed function objects, such as the one above, directly on the call site of an STL algorithm.
|
||||
</p></div><div 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="id2779428"></a>2.1. Installing the library</h3></div></div><p>
|
||||
</p></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="id2779436"></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.
|
||||
@@ -65,14 +65,14 @@ Cast expressions
|
||||
<span class="emphasis"><i>Tuple</i></span> [<a href="#cit:boost::tuple" title="[tuple]">tuple</a>] and the <span class="emphasis"><i>type_traits</i></span> [<a href="#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="id2733541"></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.
|
||||
</p></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2733553"></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="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="id2733588"></a>3. Introduction</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2733595"></a>3.1. Motivation</h3></div></div><p>The Standard Template Library (STL)
|
||||
</p></div></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="id2733600"></a>3. Introduction</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2733607"></a>3.1. Motivation</h3></div></div><p>The Standard Template Library (STL)
|
||||
[<a href="#cit:stepanov:94" title="[STL94]">STL94</a>], now part of the C++ Standard Library [<a href="#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>
|
||||
@@ -172,7 +172,7 @@ as function composition is supported implicitly.
|
||||
|
||||
</p></li></ul></div>
|
||||
|
||||
</p></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2733932"></a>3.2. Introduction to lambda expressions</h3></div></div><p>
|
||||
</p></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2733935"></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:
|
||||
|
||||
@@ -254,12 +254,12 @@ There are quite a lot of exceptions and special cases, but discussion of them is
|
||||
list<int> v(10);
|
||||
for_each(v.begin(), v.end(), _1 = 1);</pre>
|
||||
|
||||
The expression <tt>_1 = 1</tt> creates a lambda functor which assigns the value <tt>1</tt> to every element in <tt>v</tt>.<sup>[<a name="id2729061" href="#ftn.id2729061">1</a>]</sup>
|
||||
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="id2729070" href="#ftn.id2729070">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">
|
||||
list<int*> vp(10);
|
||||
vector<int*> vp(10);
|
||||
transform(v.begin(), v.end(), vp.begin(), &_1);</pre>
|
||||
|
||||
The expression <tt>&_1</tt> creates a function object for getting the address of each element in <tt>v</tt>.
|
||||
@@ -356,19 +356,18 @@ 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);
|
||||
(_1 = 2, _1 + i)(i);
|
||||
</pre>
|
||||
|
||||
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 <tt>i</tt> to it.
|
||||
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>.
|
||||
In other words, the lambda expression that is created is
|
||||
<tt>lambda x.(x = 2, x + 1)</tt> rather than
|
||||
<tt>lambda x.(x = 2, x + i)</tt>.
|
||||
|
||||
</p><p>
|
||||
|
||||
@@ -386,12 +385,12 @@ 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>
|
||||
we are creating the lambda expression <tt>lambda x.(x = 2, 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);
|
||||
(_1 = 2, _1 + ref(i))(i);
|
||||
</pre>
|
||||
|
||||
Note that <tt>ref</tt> and <tt>cref</tt> are different
|
||||
@@ -512,7 +511,7 @@ For example, the following is a valid lambda expression:
|
||||
<pre class="programlisting">cout << _1, _2[_3] = _1 && false</pre>
|
||||
</p><p>
|
||||
However, there are some restrictions that originate from the C++ operator overloading rules, and some special cases.
|
||||
</p><div class="section"><div class="titlepage"><div><h4 class="title"><a name="id2730141"></a>5.2.1. Operators that cannot be overloaded</h4></div></div><p>
|
||||
</p><div class="section"><div class="titlepage"><div><h4 class="title"><a name="id2730153"></a>5.2.1. Operators that cannot be overloaded</h4></div></div><p>
|
||||
Some operators cannot be overloaded at all (<tt>::</tt>, <tt>.</tt>, <tt>.*</tt>).
|
||||
For some operators, the requirements on return types prevent them to be overloaded to create lambda functors.
|
||||
These operators are <tt>->.</tt>, <tt>-></tt>, <tt>new</tt>, <tt>new[]</tt>, <tt>delete</tt>, <tt>delete[]</tt> and <tt>?:</tt> (the conditional operator).
|
||||
@@ -743,12 +742,32 @@ operator defined, can be used as target functions.
|
||||
|
||||
In general, BLL cannot deduce the return type of an arbitrary function object.
|
||||
|
||||
However, there is a method for giving BLL this capability for a certain
|
||||
However, there are two methods for giving BLL this capability for a certain
|
||||
function object class.
|
||||
|
||||
</p><div class="simplesect"><div class="titlepage"><div><h5 class="title"><a name="id2792562"></a>The sig template</h5></div></div><p>
|
||||
To make BLL aware of the return type(s) of a function object one needs to
|
||||
provide a member template struct
|
||||
</p><div class="simplesect"><div class="titlepage"><div><h5 class="title"><a name="id2792574"></a>The result_type typedef</h5></div></div><p>
|
||||
|
||||
The BLL supports the standard library convention of declaring the return type
|
||||
of a function object with a member typedef named <tt>result_type</tt> in the
|
||||
function object class.
|
||||
|
||||
Here is a simple example:
|
||||
<pre class="programlisting">
|
||||
struct A {
|
||||
typedef B result_type;
|
||||
B operator()(X, Y, Z);
|
||||
};
|
||||
</pre>
|
||||
|
||||
If a function object does not define a <tt>result_type</tt> typedef,
|
||||
the method described below (<tt>sig</tt> template)
|
||||
is attempted to resolve the return type of the
|
||||
function object. If a function object defines both <tt>result_type</tt>
|
||||
and <tt>sig</tt>, <tt>result_type</tt> takes precedence.
|
||||
|
||||
</p></div><div class="simplesect"><div class="titlepage"><div><h5 class="title"><a name="id2792646"></a>The sig template</h5></div></div><p>
|
||||
Another mechanism that make BLL aware of the return type(s) of a function object is defining
|
||||
member template struct
|
||||
<tt>sig<Args></tt> with a typedef
|
||||
<tt>type</tt> that specifies the return type.
|
||||
|
||||
@@ -767,9 +786,7 @@ 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 the Standard Library
|
||||
convention for defining the return type of a function
|
||||
object with the <tt>return_type</tt> typedef.
|
||||
This may seem overly complex compared to defining the <tt>result_type</tt> typedef.
|
||||
Howver, there are two significant restrictions with using just a simple
|
||||
typedef to express the return type:
|
||||
<div class="orderedlist"><ol type="1"><li><p>
|
||||
@@ -831,25 +848,7 @@ for tools that can aid in these tasks.
|
||||
The <tt>sig</tt> templates are a refined version of a similar
|
||||
mechanism first introduced in the FC++ library
|
||||
[<a href="#cit:fc++" title="[fc++]">fc++</a>].
|
||||
</p></div><p>
|
||||
Earlier versions of the library supported the Standard Library convention
|
||||
as the default, and required special actions to make the library recognize
|
||||
the <tt>sig</tt> 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 <tt>std_functor</tt>
|
||||
wrapper, that gives the function object a <tt>sig</tt>
|
||||
template based on the <tt>result_type</tt> typedef.
|
||||
For example:
|
||||
|
||||
<pre class="programlisting">
|
||||
int i = 1;
|
||||
bind(plus<int>(), _1, 1)(i); // error, no sig template
|
||||
bind(std_functor(plus<int>()), _1, 1)(i); // ok
|
||||
</pre>
|
||||
|
||||
</p></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="sect:overriding_deduced_return_type"></a>5.4. Overriding the deduced return type</h3></div></div><p>
|
||||
</p></div></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="sect:overriding_deduced_return_type"></a>5.4. Overriding the deduced return type</h3></div></div><p>
|
||||
The return type deduction system may not be able to deduce the return types of some user defined operators or bind expressions with class objects.
|
||||
|
||||
A special lambda expression type is provided for stating the return type explicitly and overriding the deduction system.
|
||||
@@ -968,7 +967,7 @@ By using <tt>var</tt> to make <tt>index</tt> a lambda expression, we get the des
|
||||
In sum, <tt>var(x)</tt> creates a nullary lambda functor,
|
||||
which stores a reference to the variable <tt>x</tt>.
|
||||
When the lambda functor is invoked, a reference to <tt>x</tt> is returned.
|
||||
</p><div class="simplesect"><div class="titlepage"><div><h4 class="title"><a name="id2793408"></a>Naming delayed constants and variables</h4></div></div><p>
|
||||
</p><div class="simplesect"><div class="titlepage"><div><h4 class="title"><a name="id2793439"></a>Naming delayed constants and variables</h4></div></div><p>
|
||||
It is possible to predefine and name a delayed variable or constant outside a lambda expression.
|
||||
The templates <tt>var_type</tt>, <tt>constant_type</tt>
|
||||
and <tt>constant_ref_type</tt> serve for this purpose.
|
||||
@@ -997,7 +996,7 @@ Here is an example of naming a delayed constant:
|
||||
constant_type<char>::type space(constant(' '));
|
||||
for_each(a.begin(),a.end(), cout << space << _1);
|
||||
</pre>
|
||||
</p></div><div class="simplesect"><div class="titlepage"><div><h4 class="title"><a name="id2793531"></a>About assignment and subscript operators</h4></div></div><p>
|
||||
</p></div><div class="simplesect"><div class="titlepage"><div><h4 class="title"><a name="id2793563"></a>About assignment and subscript operators</h4></div></div><p>
|
||||
As described in <a href="#sect:assignment_and_subscript" title="5.2.2. Assignment and subscript operators">Section 5.2.2</a>, assignment and subscripting operators are always defined as member functions.
|
||||
This means, that for expressions of the form
|
||||
<tt>x = y</tt> or <tt>x[y]</tt> to be interpreted as lambda expressions, the left-hand operand <tt>x</tt> must be a lambda expression.
|
||||
@@ -1070,13 +1069,7 @@ for_each(a, a+5,
|
||||
The BLL supports an alternative syntax for control expressions, suggested
|
||||
by Joel de Guzmann.
|
||||
By overloading the <tt>operator[]</tt> we can
|
||||
get a closer resemblance with the built-in control structures.
|
||||
For example, using this syntax the <tt>if_then</tt> example above
|
||||
can be written as:
|
||||
<pre class="programlisting">
|
||||
for_each(a.begin(), a.end(),
|
||||
if(_1 % 2 == 0)[ cout << _1 ])
|
||||
</pre>
|
||||
get a closer resemblance with the built-in control structures:
|
||||
|
||||
<pre class="programlisting">
|
||||
if_(condition)[then_part]
|
||||
@@ -1086,6 +1079,13 @@ do_[body].while_(condition)
|
||||
for_(init, condition, increment)[body]
|
||||
</pre>
|
||||
|
||||
For example, using this syntax the <tt>if_then</tt> example above
|
||||
can be written as:
|
||||
<pre class="programlisting">
|
||||
for_each(a.begin(), a.end(),
|
||||
if_(_1 % 2 == 0)[ cout << _1 ])
|
||||
</pre>
|
||||
|
||||
As more experience is gained, we may end up deprecating one or the other
|
||||
of these syntaces.
|
||||
|
||||
@@ -1284,7 +1284,7 @@ objects related to creating and destroying objects,
|
||||
showing the expression to create and call the function object,
|
||||
and the effect of evaluating that expression.
|
||||
|
||||
</p><div class="table"><p><a name="table:constructor_destructor_fos"></a><b>Table 1. Construction and destruction related function objects.</b></p><table summary="Construction and destruction related function objects." border="1"><colgroup><col><col></colgroup><thead><tr><th>Function object call</th><th>Wrapped expression</th></tr></thead><tbody><tr><td><tt>constructor<T>()(<i><tt>arg_list</tt></i>)</tt></td><td>T(<i><tt>arg_list</tt></i>)</td></tr><tr><td><tt>destructor()(a)</tt></td><td><tt>a.~A()</tt>, where <tt>a</tt> is of type <tt>A</tt></td></tr><tr><td><tt>destructor()(pa)</tt></td><td><tt>pa.->A()</tt>, where <tt>pa</tt> is of type <tt>A*</tt></td></tr><tr><td><tt>new_ptr<T>()(<i><tt>arg_list</tt></i>)</tt></td><td><tt>new T(<i><tt>arg_list</tt></i>)</tt></td></tr><tr><td><tt>new_array<T>()(sz)</tt></td><td><tt>new T[sz]</tt></td></tr><tr><td><tt>delete_ptr()(p)</tt></td><td><tt>delete p</tt></td></tr><tr><td><tt>delete_array()(p)</tt></td><td><tt>delete p[]</tt></td></tr></tbody></table></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2794800"></a>5.9. Special lambda expressions</h3></div></div><div class="section"><div class="titlepage"><div><h4 class="title"><a name="id2794808"></a>5.9.1. Preventing argument substitution</h4></div></div><p>
|
||||
</p><div class="table"><p><a name="table:constructor_destructor_fos"></a><b>Table 1. Construction and destruction related function objects.</b></p><table summary="Construction and destruction related function objects." border="1"><colgroup><col><col></colgroup><thead><tr><th>Function object call</th><th>Wrapped expression</th></tr></thead><tbody><tr><td><tt>constructor<T>()(<i><tt>arg_list</tt></i>)</tt></td><td>T(<i><tt>arg_list</tt></i>)</td></tr><tr><td><tt>destructor()(a)</tt></td><td><tt>a.~A()</tt>, where <tt>a</tt> is of type <tt>A</tt></td></tr><tr><td><tt>destructor()(pa)</tt></td><td><tt>pa->~A()</tt>, where <tt>pa</tt> is of type <tt>A*</tt></td></tr><tr><td><tt>new_ptr<T>()(<i><tt>arg_list</tt></i>)</tt></td><td><tt>new T(<i><tt>arg_list</tt></i>)</tt></td></tr><tr><td><tt>new_array<T>()(sz)</tt></td><td><tt>new T[sz]</tt></td></tr><tr><td><tt>delete_ptr()(p)</tt></td><td><tt>delete p</tt></td></tr><tr><td><tt>delete_array()(p)</tt></td><td><tt>delete p[]</tt></td></tr></tbody></table></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2794832"></a>5.9. Special lambda expressions</h3></div></div><div class="section"><div class="titlepage"><div><h4 class="title"><a name="id2794839"></a>5.9.1. Preventing argument substitution</h4></div></div><p>
|
||||
When a lambda functor is called, the default behavior is to substitute
|
||||
the actual arguments for the placeholders within all subexpressions.
|
||||
|
||||
@@ -1410,7 +1410,7 @@ int nested(const F& f) {
|
||||
}
|
||||
</pre>
|
||||
|
||||
</p></div><div class="section"><div class="titlepage"><div><h5 class="title"><a name="id2795067"></a>5.9.1.2. Protect</h5></div></div><p>
|
||||
</p></div><div class="section"><div class="titlepage"><div><h5 class="title"><a name="id2795098"></a>5.9.1.2. Protect</h5></div></div><p>
|
||||
The <tt>protect</tt> function is related to unlambda.
|
||||
|
||||
It is also used to prevent the argument substitution taking place,
|
||||
@@ -1515,7 +1515,7 @@ since calls to sub lambda functors are made inside the BLL,
|
||||
and are not affected by the non-const rvalue problem.
|
||||
</p></li></ol></div>
|
||||
|
||||
</p></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2795373"></a>5.10. Casts, sizeof and typeid</h3></div></div><div class="section"><div class="titlepage"><div><h4 class="title"><a name="sect:cast_expressions"></a>5.10.1.
|
||||
</p></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2795404"></a>5.10. Casts, sizeof and typeid</h3></div></div><div class="section"><div class="titlepage"><div><h4 class="title"><a name="sect:cast_expressions"></a>5.10.1.
|
||||
Cast expressions
|
||||
</h4></div></div><p>
|
||||
The BLL defines its counterparts for the four cast expressions
|
||||
@@ -1544,7 +1544,7 @@ int count = 0;
|
||||
for_each(a.begin(), a.end(),
|
||||
if_then(ll_dynamic_cast<derived*>(_1), ++var(count)));
|
||||
</pre>
|
||||
</p></div><div class="section"><div class="titlepage"><div><h4 class="title"><a name="id2795475"></a>5.10.2. Sizeof and typeid</h4></div></div><p>
|
||||
</p></div><div class="section"><div class="titlepage"><div><h4 class="title"><a name="id2795506"></a>5.10.2. Sizeof and typeid</h4></div></div><p>
|
||||
The BLL counterparts for these expressions are named
|
||||
<tt>ll_sizeof</tt> and <tt>ll_typeid</tt>.
|
||||
|
||||
@@ -1817,7 +1817,7 @@ public:
|
||||
Note, that we are reusing the existing specializations for the
|
||||
BLL <tt>return_type_2</tt> template,
|
||||
which require that the argument types are references.
|
||||
</p><div class="table"><p><a name="table:actions"></a><b>Table 2. Action types</b></p><table summary="Action types" border="1"><colgroup><col><col></colgroup><tbody><tr><td><tt>+</tt></td><td><tt>arithmetic_action<plus_action></tt></td></tr><tr><td><tt>-</tt></td><td><tt>arithmetic_action<minus_action></tt></td></tr><tr><td><tt>*</tt></td><td><tt>arithmetic_action<multiply_action></tt></td></tr><tr><td><tt>/</tt></td><td><tt>arithmetic_action<divide_action></tt></td></tr><tr><td><tt>%</tt></td><td><tt>arithmetic_action<remainder_action></tt></td></tr><tr><td><tt>+</tt></td><td><tt>unary_arithmetic_action<plus_action></tt></td></tr><tr><td><tt>-</tt></td><td><tt>unary_arithmetic_action<minus_action></tt></td></tr><tr><td><tt>&</tt></td><td><tt>bitwise_action<and_action></tt></td></tr><tr><td><tt>|</tt></td><td><tt>bitwise_action<or_action></tt></td></tr><tr><td><tt>~</tt></td><td><tt>bitwise_action<not_action></tt></td></tr><tr><td><tt>^</tt></td><td><tt>bitwise_action<xor_action></tt></td></tr><tr><td><tt><<</tt></td><td><tt>bitwise_action<leftshift_action_no_stream></tt></td></tr><tr><td><tt>>></tt></td><td><tt>bitwise_action<rightshift_action_no_stream></tt></td></tr><tr><td><tt>&&</tt></td><td><tt>logical_action<and_action></tt></td></tr><tr><td><tt>||</tt></td><td><tt>logical_action<or_action></tt></td></tr><tr><td><tt>!</tt></td><td><tt>logical_action<not_action></tt></td></tr><tr><td><tt><</tt></td><td><tt>relational_action<less_action></tt></td></tr><tr><td><tt>></tt></td><td><tt>relational_action<greater_action></tt></td></tr><tr><td><tt><=</tt></td><td><tt>relational_action<lessorequal_action></tt></td></tr><tr><td><tt>>=</tt></td><td><tt>relational_action<greaterorequal_action></tt></td></tr><tr><td><tt>==</tt></td><td><tt>relational_action<equal_action></tt></td></tr><tr><td><tt>!=</tt></td><td><tt>relational_action<notequal_action></tt></td></tr><tr><td><tt>+=</tt></td><td><tt>arithmetic_assignment_action<plus_action></tt></td></tr><tr><td><tt>-=</tt></td><td><tt>arithmetic_assignment_action<minus_action></tt></td></tr><tr><td><tt>*=</tt></td><td><tt>arithmetic_assignment_action<multiply_action></tt></td></tr><tr><td><tt>/=</tt></td><td><tt>arithmetic_assignment_action<divide_action></tt></td></tr><tr><td><tt>%=</tt></td><td><tt>arithmetic_assignment_action<remainder_action></tt></td></tr><tr><td><tt>&=</tt></td><td><tt>bitwise_assignment_action<and_action></tt></td></tr><tr><td><tt>=|</tt></td><td><tt>bitwise_assignment_action<or_action></tt></td></tr><tr><td><tt>^=</tt></td><td><tt>bitwise_assignment_action<xor_action></tt></td></tr><tr><td><tt><<=</tt></td><td><tt>bitwise_assignment_action<leftshift_action></tt></td></tr><tr><td><tt>>>=</tt></td><td><tt>bitwise_assignment_action<rightshift_action></tt></td></tr><tr><td><tt>++</tt></td><td><tt>pre_increment_decrement_action<increment_action></tt></td></tr><tr><td><tt>--</tt></td><td><tt>pre_increment_decrement_action<decrement_action></tt></td></tr><tr><td><tt>++</tt></td><td><tt>post_increment_decrement_action<increment_action></tt></td></tr><tr><td><tt>--</tt></td><td><tt>post_increment_decrement_action<decrement_action></tt></td></tr><tr><td><tt>&</tt></td><td><tt>other_action<address_of_action></tt></td></tr><tr><td><tt>*</tt></td><td><tt>other_action<contents_of_action></tt></td></tr><tr><td><tt>,</tt></td><td><tt>other_action<comma_action></tt></td></tr></tbody></table></div></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="id2796882"></a>7. Practical considerations</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2796888"></a>7.1. Performance</h3></div></div><p>In theory, all overhead of using STL algorithms and lambda functors
|
||||
</p><div class="table"><p><a name="table:actions"></a><b>Table 2. Action types</b></p><table summary="Action types" border="1"><colgroup><col><col></colgroup><tbody><tr><td><tt>+</tt></td><td><tt>arithmetic_action<plus_action></tt></td></tr><tr><td><tt>-</tt></td><td><tt>arithmetic_action<minus_action></tt></td></tr><tr><td><tt>*</tt></td><td><tt>arithmetic_action<multiply_action></tt></td></tr><tr><td><tt>/</tt></td><td><tt>arithmetic_action<divide_action></tt></td></tr><tr><td><tt>%</tt></td><td><tt>arithmetic_action<remainder_action></tt></td></tr><tr><td><tt>+</tt></td><td><tt>unary_arithmetic_action<plus_action></tt></td></tr><tr><td><tt>-</tt></td><td><tt>unary_arithmetic_action<minus_action></tt></td></tr><tr><td><tt>&</tt></td><td><tt>bitwise_action<and_action></tt></td></tr><tr><td><tt>|</tt></td><td><tt>bitwise_action<or_action></tt></td></tr><tr><td><tt>~</tt></td><td><tt>bitwise_action<not_action></tt></td></tr><tr><td><tt>^</tt></td><td><tt>bitwise_action<xor_action></tt></td></tr><tr><td><tt><<</tt></td><td><tt>bitwise_action<leftshift_action_no_stream></tt></td></tr><tr><td><tt>>></tt></td><td><tt>bitwise_action<rightshift_action_no_stream></tt></td></tr><tr><td><tt>&&</tt></td><td><tt>logical_action<and_action></tt></td></tr><tr><td><tt>||</tt></td><td><tt>logical_action<or_action></tt></td></tr><tr><td><tt>!</tt></td><td><tt>logical_action<not_action></tt></td></tr><tr><td><tt><</tt></td><td><tt>relational_action<less_action></tt></td></tr><tr><td><tt>></tt></td><td><tt>relational_action<greater_action></tt></td></tr><tr><td><tt><=</tt></td><td><tt>relational_action<lessorequal_action></tt></td></tr><tr><td><tt>>=</tt></td><td><tt>relational_action<greaterorequal_action></tt></td></tr><tr><td><tt>==</tt></td><td><tt>relational_action<equal_action></tt></td></tr><tr><td><tt>!=</tt></td><td><tt>relational_action<notequal_action></tt></td></tr><tr><td><tt>+=</tt></td><td><tt>arithmetic_assignment_action<plus_action></tt></td></tr><tr><td><tt>-=</tt></td><td><tt>arithmetic_assignment_action<minus_action></tt></td></tr><tr><td><tt>*=</tt></td><td><tt>arithmetic_assignment_action<multiply_action></tt></td></tr><tr><td><tt>/=</tt></td><td><tt>arithmetic_assignment_action<divide_action></tt></td></tr><tr><td><tt>%=</tt></td><td><tt>arithmetic_assignment_action<remainder_action></tt></td></tr><tr><td><tt>&=</tt></td><td><tt>bitwise_assignment_action<and_action></tt></td></tr><tr><td><tt>=|</tt></td><td><tt>bitwise_assignment_action<or_action></tt></td></tr><tr><td><tt>^=</tt></td><td><tt>bitwise_assignment_action<xor_action></tt></td></tr><tr><td><tt><<=</tt></td><td><tt>bitwise_assignment_action<leftshift_action></tt></td></tr><tr><td><tt>>>=</tt></td><td><tt>bitwise_assignment_action<rightshift_action></tt></td></tr><tr><td><tt>++</tt></td><td><tt>pre_increment_decrement_action<increment_action></tt></td></tr><tr><td><tt>--</tt></td><td><tt>pre_increment_decrement_action<decrement_action></tt></td></tr><tr><td><tt>++</tt></td><td><tt>post_increment_decrement_action<increment_action></tt></td></tr><tr><td><tt>--</tt></td><td><tt>post_increment_decrement_action<decrement_action></tt></td></tr><tr><td><tt>&</tt></td><td><tt>other_action<address_of_action></tt></td></tr><tr><td><tt>*</tt></td><td><tt>other_action<contents_of_action></tt></td></tr><tr><td><tt>,</tt></td><td><tt>other_action<comma_action></tt></td></tr></tbody></table></div></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="id2796913"></a>7. Practical considerations</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2796919"></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.
|
||||
|
||||
@@ -1887,7 +1887,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 experiensed
|
||||
Although the above tests do not include such an expression, we have experienced
|
||||
this for some seemingly simple expressions.
|
||||
|
||||
|
||||
@@ -1909,7 +1909,7 @@ The running times are expressed in arbitrary units." border="1"><colgroup><col><
|
||||
</p><p>Some additional performance testing with an earlier version of the
|
||||
library is described
|
||||
[<a href="#cit:jarvi:00" title="[Jär00]">Jär00</a>].
|
||||
</p></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2797381"></a>7.2. About compiling</h3></div></div><p>The BLL uses templates rather heavily, performing numerous recursive instantiations of the same templates.
|
||||
</p></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2797412"></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.
|
||||
@@ -1917,13 +1917,13 @@ 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.
|
||||
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.
|
||||
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="id2797442"></a>7.3. Portability</h3></div></div><p>
|
||||
</p></li></ul></div></p></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2797473"></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
|
||||
@@ -1932,7 +1932,7 @@ The BLL works with the following compilers, that is, the compilers are capable o
|
||||
)
|
||||
|
||||
</li></ul></div>
|
||||
</p><div class="section"><div class="titlepage"><div><h4 class="title"><a name="id2797482"></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:
|
||||
</p><div class="section"><div class="titlepage"><div><h4 class="title"><a name="id2797513"></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.
|
||||
@@ -1978,7 +1978,7 @@ Contains several user defined operators and the corresponding specializations fo
|
||||
Contains tests for using <tt>boost::function</tt> together with lambda functors.
|
||||
</p></li></ul></div>
|
||||
|
||||
</p></div></div></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="id2797826"></a>8. Relation to other Boost libraries</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2797834"></a>8.1. Boost Function</h3></div></div><p>Sometimes it is convenient to store lambda functors in variables.
|
||||
</p></div></div></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="id2797857"></a>8. Relation to other Boost libraries</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2797865"></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="#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.
|
||||
@@ -1986,14 +1986,14 @@ lambda functors; and these wrappers have types that are easy to type out.
|
||||
For example:
|
||||
|
||||
<pre class="programlisting">
|
||||
boost::function<int, int, int> f = _1 + _2;
|
||||
boost::function<int&, int&> g = unlambda(_1 += 10);
|
||||
boost::function<int(int, int)> f = _1 + _2;
|
||||
boost::function<int&(int&)> g = (_1 += 10);
|
||||
int i = 1, j = 2;
|
||||
f(i); // returns 3
|
||||
g(i); // sets i to = 11;
|
||||
f(i, j); // returns 3
|
||||
g(i); // sets i to = 11;
|
||||
</pre>
|
||||
|
||||
The return and parameter types of the wrapped function object must be written explicilty as template arguments to the wrapper template <tt>boost::function</tt>; even when lambda functors, which otherwise have generic parameters, are wrapped.
|
||||
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>
|
||||
@@ -2011,13 +2011,13 @@ For example:
|
||||
<pre class="programlisting">
|
||||
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;
|
||||
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="id2797938"></a>8.2. Boost Bind</h3></div></div><p>
|
||||
</p></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2797969"></a>8.2. Boost Bind</h3></div></div><p>
|
||||
<span class="emphasis"><i>The Boost Bind</i></span> [<a href="#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.
|
||||
@@ -2036,7 +2036,7 @@ 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="id2798003"></a>8.2.1. First argument of bind expression</h4></div></div>
|
||||
</p><div class="section"><div class="titlepage"><div><h4 class="title"><a name="id2798034"></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,
|
||||
@@ -2094,7 +2094,7 @@ 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="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="id2798134"></a>9. Contributors</h2></div></div>
|
||||
</p></div></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="id2798148"></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.
|
||||
@@ -2102,7 +2102,7 @@ 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="appendix"><h2 class="title" style="clear: both"><a name="id2798156"></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.
|
||||
</div><div class="appendix"><h2 class="title" style="clear: both"><a name="id2798170"></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.
|
||||
@@ -2155,18 +2155,27 @@ 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 id="id2798308" class="bibliography"><div class="titlepage"><div><h2 class="title"><a name="id2798308"></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">
|
||||
</p></div></div><div id="id2798322" class="bibliography"><div class="titlepage"><div><h2 class="title"><a name="id2798322"></a>Bibliography</h2></div></div><div class="biblioentry"><a name="cit:stepanov:94"></a><p>[STL94] <span class="authorgroup">A. A. Stepanov and M. Lee. </span><span class="title"><I>The Standard Template Library</I>. </span><span class="orgname">Hewlett-Packard Laboratories. </span><span class="pubdate">1994. </span><span class="bibliomisc">
|
||||
<a href="http://www.hpl.hp.com/techreports" target="_top">www.hpl.hp.com/techreports</a>
|
||||
. </span></p></div><div class="biblioentry"><a name="cit:sgi:02"></a><p>[SGI02] <span class="title"><I>The SGI Standard Template Library</I>. </span><span class="pubdate">2002. </span><span class="bibliomisc"><a href="http://www.sgi.com/tech/stl/" target="_top">www.sgi.com/tech/stl/</a>. </span></p></div><div class="biblioentry"><a name="cit:c++:98"></a><p>[C++98] <span class="title"><I>International Standard, Programming Languages – C++</I>. </span><span class="subtitle">ISO/IEC:14882. </span><span class="pubdate">1998. </span></p></div><div class="biblioentry"><a name="cit:jarvi:99"></a><p>[Jär99] <span class="articleinfo">
|
||||
<span class="author">Jaakko Järvi. </span>
|
||||
<span class="title"><I>C++ Function Object Binders Made Easy</I>. </span>
|
||||
. </span><span class="title"><I>Lecture Notes in Computer Science</I>. </span><span class="volumenum">1977. </span><span class="publishername">Springer. </span><span class="pubdate">2000. </span></p></div><div class="biblioentry"><a name="cit:jarvi:00"></a><p>[Jär00] <span class="author">Jaakko Järvi. </span><span class="author">Gary Powell. </span><span class="title"><I>The Lambda Library : Lambda Abstraction in C++</I>. </span><span class="orgname">Turku Centre for Computer Science. </span><span class="bibliomisc">Technical Report . </span><span class="issuenum">378. </span><span class="pubdate">2000. </span><span class="bibliomisc"><a href="http://www.tucs.fi/Publications/techreports/TR378.php" target="_top">www.tucs.fi/publications</a>. </span></p></div><div class="biblioentry"><a name="cit:jarvi:01"></a><p>[Jär01] <span class="author">Jaakko Järvi. </span><span class="author">Gary Powell. </span><span class="title"><I>The Lambda Library : Lambda Abstraction in C++</I>. </span><span class="confgroup"><span class="conftitle">Second Workshop on C++ Template Programming. </span><span class="address">Tampa Bay, OOPSLA'01. </span>. </span><span class="pubdate">2001. </span><span class="bibliomisc"><a href="http://www.oonumerics.org/tmpw01/" target="_top">www.oonumerics.org/tmpw01/</a>. </span></p></div><div class="biblioentry"><a name="cit:boost::tuple"></a><p>[tuple] <span class="title"><I>The Boost Tuple Library</I>. </span><span class="bibliomisc"><a href="http://www.boost.org/libs/tuple/doc/tuple_users_guide.html" target="_top">www.boost.org/libs/tuple/doc/tuple_users_guide.html</a>
|
||||
. </span><span class="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:jarvi:03"></a><p>[Jär03] <span class="articleinfo">
|
||||
|
||||
<span class="author">Jaakko Järvi. </span>
|
||||
|
||||
<span class="author">Gary Powell. </span>
|
||||
|
||||
<span class="author">Andrew Lumsdaine. </span>
|
||||
<span class="title"><I>The Lambda Library : unnamed functions in C++</I>. </span>
|
||||
|
||||
. </span><span class="title"><I>Software - Practice and Expreience</I>. </span><span class="volumenum">33:259-291. </span><span class="pubdate">2003. </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="footnotes"><br><hr width="100" align="left"><div class="footnote"><p><sup>[<a name="ftn.id2729061" href="#id2729061">1</a>] </sup>
|
||||
. </span><span class="pubdate">2002. </span></p></div></div><div class="footnotes"><br><hr width="100" align="left"><div class="footnote"><p><sup>[<a name="ftn.id2729070" href="#id2729070">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.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
// - casts.hpp -- BLambda Library -------------
|
||||
//
|
||||
// Copyright (C) 2000 Gary Powell (gary.powell@sierra.com)
|
||||
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// - construct.hpp -- Lambda Library -------------
|
||||
//
|
||||
// Copyright (C) 2000 Gary Powell (gary.powell@sierra.com)
|
||||
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
|
||||
@@ -1,4 +1,18 @@
|
||||
// -- core.hpp -- Boost Lambda Library -------------------------------------
|
||||
//
|
||||
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// Includes the core of LL, without any real features for client:
|
||||
//
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Boost Lambda Library -- control_constructs_common.hpp -------------------
|
||||
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000 Gary Powell (gary.powell@sierra.com)
|
||||
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// 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)
|
||||
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
|
||||
@@ -345,6 +345,7 @@ 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);
|
||||
@@ -618,6 +619,7 @@ struct function_adaptor<Result (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8,
|
||||
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8, class Arg9, class Result>
|
||||
struct function_adaptor<Result (*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9)> {
|
||||
|
||||
template<class T> struct sig { typedef Result type; };
|
||||
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
|
||||
static Result apply(Result (*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9), A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8, A9& a9) {
|
||||
return func(a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
||||
|
||||
@@ -43,9 +43,9 @@
|
||||
// Now we only have one version of is_instance_of templates, which delagate
|
||||
// all the nasty compiler tricks to is_convertible.
|
||||
|
||||
#define BOOST_LAMBDA_CLASS(N,A) BOOST_PP_COMMA_IF(N) class
|
||||
#define BOOST_LAMBDA_CLASS_ARG(N,A) BOOST_PP_COMMA_IF(N) class A##N
|
||||
#define BOOST_LAMBDA_ARG(N,A) BOOST_PP_COMMA_IF(N) A##N
|
||||
#define BOOST_LAMBDA_CLASS(z, N,A) BOOST_PP_COMMA_IF(N) class
|
||||
#define BOOST_LAMBDA_CLASS_ARG(z, N,A) BOOST_PP_COMMA_IF(N) class A##N
|
||||
#define BOOST_LAMBDA_ARG(z, N,A) BOOST_PP_COMMA_IF(N) A##N
|
||||
|
||||
#define BOOST_LAMBDA_CLASS_LIST(n, NAME) BOOST_PP_REPEAT(n, BOOST_LAMBDA_CLASS, NAME)
|
||||
|
||||
@@ -83,7 +83,7 @@ public: \
|
||||
};
|
||||
|
||||
|
||||
#define BOOST_LAMBDA_HELPER(N, A) BOOST_LAMBDA_IS_INSTANCE_OF_TEMPLATE( BOOST_PP_INC(N) )
|
||||
#define BOOST_LAMBDA_HELPER(z, N, A) BOOST_LAMBDA_IS_INSTANCE_OF_TEMPLATE( BOOST_PP_INC(N) )
|
||||
|
||||
// Generate the traits for 1-4 argument templates
|
||||
|
||||
|
||||
@@ -315,7 +315,7 @@ public:
|
||||
|
||||
|
||||
template<class RET, CALL_TEMPLATE_ARGS> RET call(CALL_FORMAL_ARGS) const {
|
||||
CALL_USE_ARGS;
|
||||
return CALL_USE_ARGS;
|
||||
}
|
||||
|
||||
template<class SigArgs> struct sig { typedef void type; };
|
||||
|
||||
@@ -436,10 +436,10 @@ namespace detail {
|
||||
|
||||
template<class RET, class A, class B>
|
||||
class member_pointer_caller {
|
||||
A a;
|
||||
B b;
|
||||
A a; B b;
|
||||
|
||||
public:
|
||||
member_pointer_caller(A aa, B bb) : a(aa), b(bb) {}
|
||||
member_pointer_caller(const A& aa, const B& bb) : a(aa), b(bb) {}
|
||||
|
||||
RET operator()() const { return (a->*b)(); }
|
||||
|
||||
@@ -589,29 +589,24 @@ struct member_pointer_action_helper<false, true> {
|
||||
|
||||
template<class RET, class A, class B>
|
||||
static RET apply(A& a, B& b) {
|
||||
|
||||
typedef typename ::boost::remove_cv<B>::type plainB;
|
||||
typedef typename detail::member_pointer<plainB>::type ret_t;
|
||||
typedef typename ::boost::remove_cv<A>::type plainA;
|
||||
|
||||
// we always add const (it is just the pointer types, not the types
|
||||
// pointed to) to make the to routes (calling and type deduction)
|
||||
// we always strip cv:s to
|
||||
// make the two routes (calling and type deduction)
|
||||
// to give the same results (and the const does not make any functional
|
||||
// difference)
|
||||
return detail::member_pointer_caller<ret_t, const A&, const B&>(a, b);
|
||||
return detail::member_pointer_caller<ret_t, plainA, plainB>(a, b);
|
||||
}
|
||||
|
||||
template<class A, class B>
|
||||
struct return_type {
|
||||
typedef typename detail::remove_reference_and_cv<B>::type plainB;
|
||||
typedef typename detail::member_pointer<plainB>::type ret_t;
|
||||
typedef typename detail::remove_reference_and_cv<A>::type plainA;
|
||||
|
||||
// we always add const (it is just the pointer types, not the types
|
||||
// pointed to)
|
||||
typedef detail::member_pointer_caller<
|
||||
ret_t,
|
||||
typename boost::add_reference<const A>::type,
|
||||
typename boost::add_reference<const B>::type
|
||||
> type;
|
||||
typedef detail::member_pointer_caller<ret_t, plainA, plainB> type;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -621,12 +616,10 @@ template<> class other_action<member_pointer_action> {
|
||||
public:
|
||||
template<class RET, class A, class B>
|
||||
static RET apply(A& a, B& b) {
|
||||
|
||||
typedef typename
|
||||
::boost::remove_cv<B>::type plainB;
|
||||
|
||||
return
|
||||
detail::member_pointer_action_helper<
|
||||
return detail::member_pointer_action_helper<
|
||||
boost::is_pointer<A>::value &&
|
||||
detail::member_pointer<plainB>::is_data_member,
|
||||
boost::is_pointer<A>::value &&
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include "boost/lambda/detail/is_instance_of.hpp"
|
||||
#include "boost/type_traits/same_traits.hpp"
|
||||
|
||||
#include "boost/indirect_reference.hpp"
|
||||
|
||||
#include <cstddef> // needed for the ptrdiff_t
|
||||
#include <iosfwd> // for istream and ostream
|
||||
|
||||
@@ -221,7 +223,7 @@ namespace detail {
|
||||
|
||||
// A is a nonreference type
|
||||
template <class A> struct contentsof_type {
|
||||
typedef typename std::iterator_traits<A>::reference type;
|
||||
typedef typename boost::indirect_reference<A>::type type;
|
||||
};
|
||||
|
||||
// this is since the nullary () in lambda_functor is always instantiated
|
||||
@@ -492,7 +494,6 @@ 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;
|
||||
};
|
||||
@@ -865,11 +866,31 @@ struct return_type_2<other_action<subscript_action>, A, B> {
|
||||
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;
|
||||
}
|
||||
|
||||
// The GCC 2.95.x uses a non-conformant deque
|
||||
#if BOOST_WORKAROUND(__GNUC__, == 2) && __GNUC_MINOR__ <= 96
|
||||
#include <deque>
|
||||
#else
|
||||
|
||||
namespace std {
|
||||
template <class T, class Allocator> class deque;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if BOOST_WORKAROUND(__GNUC__, == 3) && __GNUC_MINOR__ >=4
|
||||
#include <vector>
|
||||
#else
|
||||
|
||||
namespace std {
|
||||
template <class T, class Allocator> class vector;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace lambda {
|
||||
|
||||
@@ -27,22 +27,31 @@ namespace lambda {
|
||||
#error "Multiple defines of BOOST_LAMBDA_BE1"
|
||||
#endif
|
||||
|
||||
// For all BOOSTA_LAMBDA_BE* macros:
|
||||
|
||||
// CONSTA must be either 'A' or 'const A'
|
||||
// CONSTB must be either 'B' or 'const B'
|
||||
|
||||
// It is stupid to have the names A and B as macro arguments, but it avoids
|
||||
// the need to pass in emtpy macro arguments, which gives warnings on some
|
||||
// compilers
|
||||
|
||||
#define BOOST_LAMBDA_BE1(OPER_NAME, ACTION, CONSTA, CONSTB, CONVERSION) \
|
||||
template<class Arg, class B> \
|
||||
inline const \
|
||||
lambda_functor< \
|
||||
lambda_functor_base< \
|
||||
ACTION, \
|
||||
tuple<lambda_functor<Arg>, typename CONVERSION <CONSTB B>::type> \
|
||||
tuple<lambda_functor<Arg>, typename CONVERSION <CONSTB>::type> \
|
||||
> \
|
||||
> \
|
||||
OPER_NAME (const lambda_functor<Arg>& a, CONSTB B& b) { \
|
||||
OPER_NAME (const lambda_functor<Arg>& a, CONSTB& b) { \
|
||||
return \
|
||||
lambda_functor_base< \
|
||||
ACTION, \
|
||||
tuple<lambda_functor<Arg>, typename CONVERSION <CONSTB B>::type> \
|
||||
tuple<lambda_functor<Arg>, typename CONVERSION <CONSTB>::type> \
|
||||
> \
|
||||
(tuple<lambda_functor<Arg>, typename CONVERSION <CONSTB B>::type>(a, b)); \
|
||||
(tuple<lambda_functor<Arg>, typename CONVERSION <CONSTB>::type>(a, b)); \
|
||||
}
|
||||
|
||||
|
||||
@@ -56,16 +65,16 @@ inline const \
|
||||
lambda_functor< \
|
||||
lambda_functor_base< \
|
||||
ACTION, \
|
||||
tuple<typename CONVERSION <CONSTA A>::type, lambda_functor<Arg> > \
|
||||
tuple<typename CONVERSION <CONSTA>::type, lambda_functor<Arg> > \
|
||||
> \
|
||||
> \
|
||||
OPER_NAME (CONSTA A& a, const lambda_functor<Arg>& b) { \
|
||||
OPER_NAME (CONSTA& a, const lambda_functor<Arg>& b) { \
|
||||
return \
|
||||
lambda_functor_base< \
|
||||
ACTION, \
|
||||
tuple<typename CONVERSION <CONSTA A>::type, lambda_functor<Arg> > \
|
||||
tuple<typename CONVERSION <CONSTA>::type, lambda_functor<Arg> > \
|
||||
> \
|
||||
(tuple<typename CONVERSION <CONSTA A>::type, lambda_functor<Arg> >(a, b)); \
|
||||
(tuple<typename CONVERSION <CONSTA>::type, lambda_functor<Arg> >(a, b)); \
|
||||
}
|
||||
|
||||
|
||||
@@ -100,36 +109,37 @@ 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, 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_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_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)
|
||||
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)
|
||||
|
||||
|
||||
// A special trick for comma operator for correct preprocessing
|
||||
@@ -139,9 +149,9 @@ BOOST_LAMBDA_BE(operator^=, bitwise_assignment_action<xor_action>, , const, refe
|
||||
|
||||
#define BOOST_LAMBDA_COMMA_OPERATOR_NAME operator,
|
||||
|
||||
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)
|
||||
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)
|
||||
|
||||
|
||||
|
||||
@@ -197,8 +207,8 @@ template<class T> struct convert_istream_to_ref_others_to_c_plain_by_default {
|
||||
|
||||
} // detail
|
||||
|
||||
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)
|
||||
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)
|
||||
|
||||
|
||||
// special case for io_manipulators.
|
||||
@@ -253,17 +263,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, CONST) \
|
||||
#define BOOST_LAMBDA_PTR_ARITHMETIC_E1(OPER_NAME, ACTION, CONSTB) \
|
||||
template<class Arg, int N, class B> \
|
||||
inline const \
|
||||
lambda_functor< \
|
||||
lambda_functor_base<ACTION, tuple<lambda_functor<Arg>, CONST B(&)[N]> > \
|
||||
lambda_functor_base<ACTION, tuple<lambda_functor<Arg>, CONSTB(&)[N]> > \
|
||||
> \
|
||||
OPER_NAME (const lambda_functor<Arg>& a, CONST B(&b)[N]) \
|
||||
OPER_NAME (const lambda_functor<Arg>& a, CONSTB(&b)[N]) \
|
||||
{ \
|
||||
return lambda_functor< \
|
||||
lambda_functor_base<ACTION, tuple<lambda_functor<Arg>, CONST B(&)[N]> > \
|
||||
>(tuple<lambda_functor<Arg>, CONST B(&)[N]>(a, b)); \
|
||||
lambda_functor_base<ACTION, tuple<lambda_functor<Arg>, CONSTB(&)[N]> > \
|
||||
>(tuple<lambda_functor<Arg>, CONSTB(&)[N]>(a, b)); \
|
||||
}
|
||||
|
||||
|
||||
@@ -271,31 +281,31 @@ OPER_NAME (const lambda_functor<Arg>& a, CONST B(&b)[N]) \
|
||||
#error "Multiple defines of BOOST_LAMBDA_PTR_ARITHMETIC_E2"
|
||||
#endif
|
||||
|
||||
#define BOOST_LAMBDA_PTR_ARITHMETIC_E2(OPER_NAME, ACTION, CONST) \
|
||||
#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<CONST A(&)[N], lambda_functor<Arg> > > \
|
||||
lambda_functor_base<ACTION, tuple<CONSTA(&)[N], lambda_functor<Arg> > > \
|
||||
> \
|
||||
OPER_NAME (CONST A(&a)[N], const lambda_functor<Arg>& b) \
|
||||
OPER_NAME (CONSTA(&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)); \
|
||||
lambda_functor_base<ACTION, tuple<CONSTA(&)[N], lambda_functor<Arg> > > \
|
||||
(tuple<CONSTA(&)[N], lambda_functor<Arg> >(a, b)); \
|
||||
}
|
||||
|
||||
|
||||
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<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<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>, )
|
||||
BOOST_LAMBDA_PTR_ARITHMETIC_E2(operator-, arithmetic_action<minus_action>, const)
|
||||
BOOST_LAMBDA_PTR_ARITHMETIC_E2(operator-, arithmetic_action<minus_action>, A)
|
||||
BOOST_LAMBDA_PTR_ARITHMETIC_E2(operator-, arithmetic_action<minus_action>, const A)
|
||||
|
||||
|
||||
#undef BOOST_LAMBDA_BE1
|
||||
|
||||
@@ -257,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 Ret apply(A&) {}
|
||||
template<class Ret, class A> static void apply(A&) {}
|
||||
};
|
||||
|
||||
template<class Args> struct return_type_N<voidifier_action, Args> {
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#ifndef BOOST_LAMBDA_RETURN_TYPE_TRAITS_HPP
|
||||
#define BOOST_LAMBDA_RETURN_TYPE_TRAITS_HPP
|
||||
|
||||
#include "boost/mpl/aux_/has_xxx.hpp"
|
||||
|
||||
#include <cstddef> // needed for the ptrdiff_t
|
||||
|
||||
namespace boost {
|
||||
@@ -239,6 +241,25 @@ 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 > {
|
||||
@@ -251,7 +272,11 @@ 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 function_adaptor<plain_Func>::template sig<Args>::type type;
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Boost Lambda Library -- if.hpp ------------------------------------------
|
||||
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000 Gary Powell (gary.powell@sierra.com)
|
||||
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
|
||||
// Copyright (C) 2001-2002 Joel de Guzman
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Boost Lambda Library -- loops.hpp ----------------------------------------
|
||||
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000 Gary Powell (gary.powell@sierra.com)
|
||||
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Boost Lambda Library -- switch.hpp -----------------------------------
|
||||
//
|
||||
// Copyright (C) 2000 Gary Powell (gary.powell@sierra.com)
|
||||
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
|
||||
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
@@ -287,10 +287,10 @@ public:
|
||||
// BOOST_LAMBDA_A_I_LIST(N, X) is a list of form X0, X1, ..., XN
|
||||
// BOOST_LAMBDA_A_I_B_LIST(N, X, Y) is a list of form X0 Y, X1 Y, ..., XN Y
|
||||
|
||||
#define BOOST_LAMBDA_A_I(i, A) \
|
||||
#define BOOST_LAMBDA_A_I(z, i, A) \
|
||||
BOOST_PP_COMMA_IF(i) BOOST_PP_CAT(A,i)
|
||||
|
||||
#define BOOST_LAMBDA_A_I_B(i, T) \
|
||||
#define BOOST_LAMBDA_A_I_B(z, i, T) \
|
||||
BOOST_PP_COMMA_IF(i) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2,0,T),i) BOOST_PP_TUPLE_ELEM(2,1,T)
|
||||
|
||||
#define BOOST_LAMBDA_A_I_LIST(i, A) \
|
||||
@@ -301,7 +301,7 @@ BOOST_PP_REPEAT(i,BOOST_LAMBDA_A_I_B, (A,B))
|
||||
|
||||
|
||||
// Switch related macros -------------------------------------------
|
||||
#define BOOST_LAMBDA_SWITCH_CASE_BLOCK(N, A) \
|
||||
#define BOOST_LAMBDA_SWITCH_CASE_BLOCK(z, N, A) \
|
||||
case Case##N: \
|
||||
detail::select(::boost::tuples::get<BOOST_PP_INC(N)>(args), CALL_ACTUAL_ARGS); \
|
||||
break;
|
||||
@@ -414,7 +414,7 @@ switch_statement(const lambda_functor<TestArg>& a1) {
|
||||
}
|
||||
|
||||
|
||||
#define HELPER(N, FOO) \
|
||||
#define HELPER(z, N, FOO) \
|
||||
BOOST_PP_COMMA_IF(N) \
|
||||
BOOST_PP_CAT( \
|
||||
const tagged_lambda_functor<detail::switch_case_tag<TagData, \
|
||||
@@ -463,11 +463,11 @@ BOOST_LAMBDA_SWITCH_NO_DEFAULT_CASE(N) \
|
||||
BOOST_LAMBDA_SWITCH_WITH_DEFAULT_CASE(N)
|
||||
|
||||
// Use this to avoid case 0, these macros work only from case 1 upwards
|
||||
#define BOOST_LAMBDA_SWITCH_HELPER(N, A) \
|
||||
#define BOOST_LAMBDA_SWITCH_HELPER(z, N, A) \
|
||||
BOOST_LAMBDA_SWITCH( BOOST_PP_INC(N) )
|
||||
|
||||
// Use this to avoid cases 0 and 1, these macros work only from case 2 upwards
|
||||
#define BOOST_LAMBDA_SWITCH_STATEMENT_HELPER(N, A) \
|
||||
#define BOOST_LAMBDA_SWITCH_STATEMENT_HELPER(z, N, A) \
|
||||
BOOST_LAMBDA_SWITCH_STATEMENT(BOOST_PP_INC(N))
|
||||
|
||||
|
||||
|
||||
8
index.html
Normal file
8
index.html
Normal file
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0; URL=doc/index.html">
|
||||
</head>
|
||||
<body>
|
||||
Automatic redirection failed, please go to <a href="doc/index.html">doc/index.html</a>
|
||||
</body>
|
||||
</html>
|
||||
93
test/Jamfile
Normal file
93
test/Jamfile
Normal file
@@ -0,0 +1,93 @@
|
||||
subproject libs/lambda/test ;
|
||||
|
||||
unit-test is_instance_of_test
|
||||
: is_instance_of_test.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test algortihm_test
|
||||
: algorithm_test.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test operator_tests_simple
|
||||
: operator_tests_simple.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test member_pointer_test
|
||||
: member_pointer_test.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test control_structures
|
||||
: control_structures.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test switch_construct
|
||||
: switch_construct.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test bind_tests_simple
|
||||
: bind_tests_simple.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test bind_tests_advanced
|
||||
: bind_tests_advanced.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test bll_and_function
|
||||
: bll_and_function.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test constructor_tests
|
||||
: constructor_tests.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test extending_rt_traits
|
||||
: extending_rt_traits.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test bind_tests_simple_f_refs
|
||||
: bind_tests_simple_f_refs.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test cast_test
|
||||
: cast_test.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test phoenix_control_structures
|
||||
: phoenix_control_structures.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
unit-test exception_test
|
||||
: exception_test.cpp
|
||||
<lib>../../test/build/test_exec_monitor
|
||||
: <sysinclude>$(BOOST_ROOT)
|
||||
;
|
||||
|
||||
|
||||
66
test/algorithm_test.cpp
Normal file
66
test/algorithm_test.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
// bll_and_function.cpp - The Boost Lambda Library -----------------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// test using BLL and boost::function
|
||||
|
||||
//#include <boost/test/minimal.hpp> // see "Header Implementation Option"
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
#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_TEST(sum == (199 + 1)/ 2 * 199);
|
||||
}
|
||||
|
||||
// More tests needed (for all algorithms)
|
||||
|
||||
int test_main(int, char *[]) {
|
||||
|
||||
test_foreach();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
// bind_tests_advanced.cpp --------------------------------
|
||||
// bind_tests_advanced.cpp -- The Boost Lambda Library ------------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
// bind_tests_simple.cpp --------------------------------
|
||||
// bind_tests_simple.cpp -- The Boost Lambda Library ------------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
@@ -31,6 +48,18 @@ 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()
|
||||
@@ -47,6 +76,14 @@ void test_member_functions()
|
||||
BOOST_TEST(bind(&A::add, _1, 1)(a) == 11);
|
||||
BOOST_TEST(bind(&A::add, _1, 1)(make_const(&a)) == 11);
|
||||
|
||||
BOOST_TEST(bind(&A::add2, _1, 1, 1)(a) == 12);
|
||||
BOOST_TEST(bind(&A::add3, _1, 1, 1, 1)(a) == 13);
|
||||
BOOST_TEST(bind(&A::add4, _1, 1, 1, 1, 1)(a) == 14);
|
||||
BOOST_TEST(bind(&A::add5, _1, 1, 1, 1, 1, 1)(a) == 15);
|
||||
BOOST_TEST(bind(&A::add6, _1, 1, 1, 1, 1, 1, 1)(a) == 16);
|
||||
BOOST_TEST(bind(&A::add7, _1, 1, 1, 1, 1, 1, 1, 1)(a) == 17);
|
||||
BOOST_TEST(bind(&A::add8, _1, 1, 1, 1, 1, 1, 1, 1, 1)(a) == 18);
|
||||
|
||||
// This should fail, as lambda functors store arguments as const
|
||||
// bind(&A::add, a, _1);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
// bind_tests_simple.cpp --------------------------------
|
||||
// bind_tests_simple.cpp -- The Boost Lambda Library ------------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
@@ -1,4 +1,18 @@
|
||||
// bll_and_function.cpp --------------------------------
|
||||
// bll_and_function.cpp - The Boost Lambda Library -----------------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// test using BLL and boost::function
|
||||
|
||||
@@ -21,13 +35,13 @@ using namespace std;
|
||||
|
||||
void test_function() {
|
||||
|
||||
boost::function<int, int, int> f;
|
||||
boost::function<int (int, int)> f;
|
||||
f = _1 + _2;
|
||||
|
||||
BOOST_TEST(f(1, 2)== 3);
|
||||
|
||||
int i=1; int j=2;
|
||||
boost::function<int&, int&, int> g = _1 += _2;
|
||||
boost::function<int& (int&, int)> g = _1 += _2;
|
||||
g(i, j);
|
||||
BOOST_TEST(i==3);
|
||||
|
||||
@@ -35,7 +49,7 @@ void test_function() {
|
||||
|
||||
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_TEST(*sum == 5);
|
||||
delete sum;
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
// cast_tests.cpp --------------------------------
|
||||
// cast_tests.cpp -- The Boost Lambda Library ------------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
// constructor_tests.cpp --------------------------------
|
||||
// constructor_tests.cpp -- The Boost Lambda Library ------------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
@@ -1,9 +1,28 @@
|
||||
// -- control_structures.cpp -- The Boost Lambda Library ------------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
#include "boost/lambda/lambda.hpp"
|
||||
#include "boost/lambda/if.hpp"
|
||||
#include "boost/lambda/loops.hpp"
|
||||
#include "boost/minmax.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
@@ -87,8 +106,8 @@ void simple_ifs () {
|
||||
|
||||
int x, y;
|
||||
x = -1; y = 1;
|
||||
BOOST_TEST(if_then_else_return(_1 < _2, _2, _1)(x, y) == std::max(x ,y));
|
||||
BOOST_TEST(if_then_else_return(_1 < _2, _2, _1)(y, x) == std::max(x ,y));
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
// -- exception_test.cpp -- The Boost Lambda Library ------------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
// extending_return_type_traits.cpp --------------------------------
|
||||
// extending_return_type_traits.cpp -- The Boost Lambda Library --------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
// is_convertible_to_template_test.cpp ----------------------------
|
||||
// is_instance_of_test.cpp -- The Boost Lambda Library ------------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
// member_pointer_test.cpp --------------------------------
|
||||
// member_pointer_test.cpp -- The Boost Lambda Library ------------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
// operator_tests_simple.cpp --------------------------------
|
||||
// operator_tests_simple.cpp -- The Boost Lambda Library ---------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
// phoenix_style_control_structures.cpp --------------------------------
|
||||
// phoenix_style_control_structures.cpp -- The Boost Lambda Library ------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
@@ -21,11 +38,9 @@ using namespace boost::lambda;
|
||||
using namespace std;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// If-else, while, do-while, for tatements
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// If-else, while, do-while, for statements
|
||||
|
||||
|
||||
int test_main(int, char *[]) {
|
||||
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
// switch_test.cpp --------------------------------
|
||||
// switch_test.cpp -- The Boost Lambda Library --------------------------
|
||||
//
|
||||
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// For more information, see www.boost.org
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
|
||||
#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
|
||||
|
||||
Reference in New Issue
Block a user