2
0
mirror of https://github.com/boostorg/lambda.git synced 2026-01-21 04:52:25 +00:00

Compare commits

..

2 Commits

Author SHA1 Message Date
Jaakko Järvi
4bdba37066 adding dummy usages of some arugments to avoid unused argument warnings
[SVN r13923]
2002-05-15 17:16:52 +00:00
nobody
aa3bf071a8 This commit was manufactured by cvs2svn to create branch 'RC_1_28_0'.
[SVN r13795]
2002-05-10 04:34:27 +00:00
24 changed files with 156 additions and 298 deletions

View File

@@ -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="id2808790"></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.

View File

@@ -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="id2790112"></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="id2742981"></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;

View File

@@ -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="id2743023"></a>3. Introduction</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2743030"></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="id2741479"></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:

View File

@@ -20,7 +20,7 @@ There are quite a lot of exceptions and special cases, but discussion of them is
list&lt;int&gt; v(10);
for_each(v.begin(), v.end(), _1 = 1);</pre>
The expression <tt>_1 = 1</tt> creates a lambda functor which assigns the value <tt>1</tt> to every element in <tt>v</tt>.<sup>[<a name="id2739587" href="#ftn.id2739587">1</a>]</sup>
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="id2739736" href="#ftn.id2739736">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>:
@@ -206,7 +206,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.id2739736" href="#id2739736">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.

View File

@@ -10,6 +10,7 @@ This section describes different categories of lambda expressions in details.
We devote a separate section for each of the possible forms of a lambda expression.
</p><div class="section"><div class="titlepage"><div><h3 class="title"><a name="sect:placeholders"></a>5.1. Placeholders</h3></div></div><p>
The BLL defines three placeholder types: <tt>placeholder1_type</tt>, <tt>placeholder2_type</tt> and <tt>placeholder3_type</tt>.
BLL has a predefined placeholder variable for each placeholder type: <tt>_1</tt>, <tt>_2</tt> and <tt>_3</tt>.
@@ -77,7 +78,7 @@ For example, the following is a valid lambda expression:
<pre class="programlisting">cout &lt;&lt; _1, _2[_3] = _1 &amp;&amp; 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="id2740751"></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>-&gt;.</tt>, <tt>-&gt;</tt>, <tt>new</tt>, <tt>new[]</tt>, <tt>delete</tt>, <tt>delete[]</tt> and <tt>?:</tt> (the conditional operator).
@@ -242,7 +243,6 @@ This creates some asymmetry between the lambda functor and the original member f
class A {
int i; mutable int j;
public:
A(int ii, int jj) : i(ii), j(jj) {};
void set_i(int x) { i = x; };
void set_j(int x) const { j = x; };
@@ -281,27 +281,7 @@ A a(0,0);
bind(&amp;A::set_i, _1, 1)(a); // a.i == 1
bind(&amp;A::set_j, _1, 1)(a); // a.j == 1
</pre>
</p></div><div class="section"><div class="titlepage"><div><h4 class="title"><a name="sect:members_variables_as_targets"></a>5.3.3. Member variables as targets</h4></div></div><p>
A pointer to a member variable is not really a function, but
the first argument to the <tt>bind</tt> function can nevertheless
be a pointer to a member variable.
Invoking such a bind expression returns a reference to the data member.
For example:
<pre class="programlisting">
struct A { int data; };
A a;
bind(&amp;A::data, _1)(a) = 1; // a.data == 1
</pre>
The cv-qualifiers of the object whose member is accessed are respected.
For example, the following tries to write into a const location:
<pre class="programlisting">
const A ca = a;
bind(&amp;A::data, _1)(ca) = 1; // error
</pre>
</p></div><div class="section"><div class="titlepage"><div><h4 class="title"><a name="sect:function_objects_as_targets"></a>5.3.4. Function objects as targets</h4></div></div><p>
</p></div><div class="section"><div class="titlepage"><div><h4 class="title"><a name="sect:function_objects_as_targets"></a>5.3.3. Function objects as targets</h4></div></div><p>
Function objects, that is, class objects which have the function call
operator defined, can be used as target functions.
@@ -311,7 +291,7 @@ 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
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>
</p><div class="simplesect"><div class="titlepage"><div><h5 class="title"><a name="id2803214"></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
<tt>sig&lt;Args&gt;</tt> with a typedef
@@ -533,7 +513,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="id2804059"></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 +542,7 @@ Here is an example of naming a delayed constant:
constant_type&lt;char&gt;::type space(constant(' '));
for_each(a.begin(),a.end(), cout &lt;&lt; space &lt;&lt; _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="id2804183"></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.
@@ -849,7 +829,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&lt;T&gt;()(<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.-&gt;A()</tt>, where <tt>pa</tt> is of type <tt>A*</tt></td></tr><tr><td><tt>new_ptr&lt;T&gt;()(<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&lt;T&gt;()(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&lt;T&gt;()(<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.-&gt;A()</tt>, where <tt>pa</tt> is of type <tt>A*</tt></td></tr><tr><td><tt>new_ptr&lt;T&gt;()(<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&lt;T&gt;()(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="id2805452"></a>5.9. Special lambda expressions</h3></div></div><div class="section"><div class="titlepage"><div><h4 class="title"><a name="id2805459"></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 +955,7 @@ int nested(const F&amp; 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="id2805719"></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 +1060,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="id2806025"></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 +1089,7 @@ int count = 0;
for_each(a.begin(), a.end(),
if_then(ll_dynamic_cast&lt;derived*&gt;(_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="id2806127"></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>.

View File

@@ -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="id2807534"></a>7. Practical considerations</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2807540"></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.
@@ -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="id2808033"></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.
@@ -111,7 +111,7 @@ This can make the error messages very long and difficult to interpret, particula
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="id2808094"></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="id2808133"></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.

View File

@@ -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="id2808478"></a>8. Relation to other Boost libraries</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2808486"></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.
@@ -44,7 +44,7 @@ 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="id2808590"></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="id2808654"></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,

View File

@@ -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="id2808769"></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.

View File

@@ -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="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="id2808943" class="bibliography"><div class="titlepage"><div><h2 class="title"><a name="id2808943"></a>Bibliography</h2></div></div><div class="biblioentry"><a name="cit:stepanov:94"></a><p>[STL94] <span class="authorgroup">A. A. Stepanov and M. Lee. </span><span class="title"><I>The Standard Template Library</I>. </span><span class="orgname">Hewlett-Packard Laboratories. </span><span class="pubdate">1994. </span><span class="bibliomisc">
<a href="http://www.hpl.hp.com/techreports" target="_top">www.hpl.hp.com/techreports</a>
. </span></p></div><div class="biblioentry"><a name="cit:sgi:02"></a><p>[SGI02] <span class="title"><I>The SGI Standard Template Library</I>. </span><span class="pubdate">2002. </span><span class="bibliomisc"><a href="http://www.sgi.com/tech/stl/" target="_top">www.sgi.com/tech/stl/</a>. </span></p></div><div class="biblioentry"><a name="cit:c++:98"></a><p>[C++98] <span class="title"><I>International Standard, Programming Languages &#8211; C++</I>. </span><span class="subtitle">ISO/IEC:14882. </span><span class="pubdate">1998. </span></p></div><div class="biblioentry"><a name="cit:jarvi:99"></a><p>[Jär99] <span class="articleinfo">
<span class="author">Jaakko Järvi. </span>

View File

@@ -1074,7 +1074,6 @@ This creates some asymmetry between the lambda functor and the original member f
class A {
int i; mutable int j;
public:
A(int ii, int jj) : i(ii), j(jj) {};
void set_i(int x) { i = x; };
void set_j(int x) const { j = x; };
@@ -1120,32 +1119,6 @@ bind(&A::set_j, _1, 1)(a); // a.j == 1]]>
</para>
</section>
<section id="sect:members_variables_as_targets">
<title>Member variables as targets</title>
<para>
A pointer to a member variable is not really a function, but
the first argument to the <literal>bind</literal> function can nevertheless
be a pointer to a member variable.
Invoking such a bind expression returns a reference to the data member.
For example:
<programlisting>
<![CDATA[struct A { int data; };
A a;
bind(&A::data, _1)(a) = 1; // a.data == 1]]>
</programlisting>
The cv-qualifiers of the object whose member is accessed are respected.
For example, the following tries to write into a const location:
<programlisting>
<![CDATA[const A ca = a;
bind(&A::data, _1)(ca) = 1; // error]]>
</programlisting>
</para>
</section>
<section id="sect:function_objects_as_targets">
<title>Function objects as targets</title>

View File

@@ -8,14 +8,14 @@
The Boost Lambda Library"><link rel="next" href="ar01s02.html" title="2. Getting Started"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">
C++ BOOST
The Boost Lambda Library</th></tr><tr><td width="20%" align="left"> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ar01s02.html">Next</a></td></tr></table><hr></div><div class="article"><div class="titlepage"><div><h1 class="title"><a name="id2733457"></a>
The Boost Lambda Library</th></tr><tr><td width="20%" align="left"> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ar01s02.html">Next</a></td></tr></table><hr></div><div class="article"><div class="titlepage"><div><h1 class="title"><a name="id2733458"></a>
<span class="inlinemediaobject"><img src="../../../c++boost.gif" alt="C++ BOOST"></span>
The Boost Lambda Library</h1></div><div><p class="copyright">Copyright © 1999-2002 Jaakko Järvi, Gary Powell</p></div><div><div class="legalnotice"><p>
The Boost Lambda Library is free software; Permission to copy,
use, modify and distribute this software and its documentation is granted, provided this copyright
notice appears in all copies.
</p></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt>1. <a href="index.html#introduction">In a nutshell</a></dt><dt>2. <a href="ar01s02.html">Getting Started</a></dt><dd><dl><dt>2.1. <a href="ar01s02.html#id2790109">Installing the library</a></dt><dt>2.2. <a href="ar01s02.html#id2741935">Conventions used in this document</a></dt></dl></dd><dt>3. <a href="ar01s03.html">Introduction</a></dt><dd><dl><dt>3.1. <a href="ar01s03.html#id2741989">Motivation</a></dt><dt>3.2. <a href="ar01s03.html#id2742784">Introduction to lambda expressions</a></dt></dl></dd><dt>4. <a href="ar01s04.html">Using the library</a></dt><dd><dl><dt>4.1. <a href="ar01s04.html#sect:introductory_examples">Introductory Examples</a></dt><dt>4.2. <a href="ar01s04.html#sect:parameter_and_return_types">Parameter and return types of lambda functors</a></dt><dt>4.3. <a href="ar01s04.html#sect:actual_arguments_to_lambda_functors">About actual arguments to lambda functors</a></dt><dt>4.4. <a href="ar01s04.html#sect:storing_bound_arguments">Storing bound arguments in lambda functions</a></dt></dl></dd><dt>5. <a href="ar01s05.html">Lambda expressions in details</a></dt><dd><dl><dt>5.1. <a href="ar01s05.html#sect:placeholders">Placeholders</a></dt><dt>5.2. <a href="ar01s05.html#sect:operator_expressions">Operator expressions</a></dt><dt>5.3. <a href="ar01s05.html#sect:bind_expressions">Bind expressions</a></dt><dt>5.4. <a href="ar01s05.html#sect:overriding_deduced_return_type">Overriding the deduced return type</a></dt><dt>5.5. <a href="ar01s05.html#sect:delaying_constants_and_variables">Delaying constants and variables</a></dt><dt>5.6. <a href="ar01s05.html#sect:lambda_expressions_for_control_structures">Lambda expressions for control structures</a></dt><dt>5.7. <a href="ar01s05.html#sect:exceptions">Exceptions</a></dt><dt>5.8. <a href="ar01s05.html#sect:construction_and_destruction">Construction and destruction</a></dt><dt>5.9. <a href="ar01s05.html#id2805476">Special lambda expressions</a></dt><dt>5.10. <a href="ar01s05.html#id2806049">Casts, sizeof and typeid</a></dt><dt>5.11. <a href="ar01s05.html#sect:nested_stl_algorithms">Nesting STL algorithm invocations</a></dt></dl></dd><dt>6. <a href="ar01s06.html">Extending return type deduction system</a></dt><dt>7. <a href="ar01s07.html">Practical considerations</a></dt><dd><dl><dt>7.1. <a href="ar01s07.html#id2807564">Performance</a></dt><dt>7.2. <a href="ar01s07.html#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#id2790112">Installing the library</a></dt><dt>2.2. <a href="ar01s02.html#id2742981">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#id2743030">Motivation</a></dt><dt>3.2. <a href="ar01s03.html#id2741479">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#id2805452">Special lambda expressions</a></dt><dt>5.10. <a href="ar01s05.html#id2806025">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#id2807540">Performance</a></dt><dt>7.2. <a href="ar01s07.html#id2808033">About compiling</a></dt><dt>7.3. <a href="ar01s07.html#id2808094">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#id2808486">Boost Function</a></dt><dt>8.2. <a href="ar01s08.html#id2808590">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>

View File

@@ -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="id2588587"></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="#id2779360">Installing the library</a></dt><dt>2.2. <a href="#id2734043">Conventions used in this document</a></dt></dl></dd><dt>3. <a href="#id2734090">Introduction</a></dt><dd><dl><dt>3.1. <a href="#id2734098">Motivation</a></dt><dt>3.2. <a href="#id2735227">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="#id2794778">Special lambda expressions</a></dt><dt>5.10. <a href="#id2795351">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="#id2796860">Practical considerations</a></dt><dd><dl><dt>7.1. <a href="#id2796866">Performance</a></dt><dt>7.2. <a href="#id2797359">About compiling</a></dt><dt>7.3. <a href="#id2797420">Portability</a></dt></dl></dd><dt>8. <a href="#id2797804">Relation to other Boost libraries</a></dt><dd><dl><dt>8.1. <a href="#id2797812">Boost Function</a></dt><dt>8.2. <a href="#id2797916">Boost Bind</a></dt></dl></dd><dt>9. <a href="#id2798095">Contributors</a></dt><dt>A. <a href="#id2798117">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="#id2798269">Bibliography</a></dt></dl></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="introduction"></a>1. In a nutshell</h2></div></div><p>
The Boost Lambda Library (BLL in the sequel) is a C++ template
library, which implements form of <span class="emphasis"><i>lambda abstractions</i></span> for C++.
@@ -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 &#8216;body&#8217; of the function is evaluated.
</p><p>The essence of BLL is letting you define small unnamed function objects, such as the one above, directly on the call site of an STL algorithm.
</p></div><div 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="id2779360"></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="id2734043"></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="id2734090"></a>3. Introduction</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2734098"></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="id2735227"></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,7 +254,7 @@ There are quite a lot of exceptions and special cases, but discussion of them is
list&lt;int&gt; v(10);
for_each(v.begin(), v.end(), _1 = 1);</pre>
The expression <tt>_1 = 1</tt> creates a lambda functor which assigns the value <tt>1</tt> to every element in <tt>v</tt>.<sup>[<a name="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="id2729011" href="#ftn.id2729011">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>:
@@ -445,6 +445,7 @@ This section describes different categories of lambda expressions in details.
We devote a separate section for each of the possible forms of a lambda expression.
</p><div class="section"><div class="titlepage"><div><h3 class="title"><a name="sect:placeholders"></a>5.1. Placeholders</h3></div></div><p>
The BLL defines three placeholder types: <tt>placeholder1_type</tt>, <tt>placeholder2_type</tt> and <tt>placeholder3_type</tt>.
BLL has a predefined placeholder variable for each placeholder type: <tt>_1</tt>, <tt>_2</tt> and <tt>_3</tt>.
@@ -512,7 +513,7 @@ For example, the following is a valid lambda expression:
<pre class="programlisting">cout &lt;&lt; _1, _2[_3] = _1 &amp;&amp; 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="id2730025"></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>-&gt;.</tt>, <tt>-&gt;</tt>, <tt>new</tt>, <tt>new[]</tt>, <tt>delete</tt>, <tt>delete[]</tt> and <tt>?:</tt> (the conditional operator).
@@ -677,7 +678,6 @@ This creates some asymmetry between the lambda functor and the original member f
class A {
int i; mutable int j;
public:
A(int ii, int jj) : i(ii), j(jj) {};
void set_i(int x) { i = x; };
void set_j(int x) const { j = x; };
@@ -716,27 +716,7 @@ A a(0,0);
bind(&amp;A::set_i, _1, 1)(a); // a.i == 1
bind(&amp;A::set_j, _1, 1)(a); // a.j == 1
</pre>
</p></div><div class="section"><div class="titlepage"><div><h4 class="title"><a name="sect:members_variables_as_targets"></a>5.3.3. Member variables as targets</h4></div></div><p>
A pointer to a member variable is not really a function, but
the first argument to the <tt>bind</tt> function can nevertheless
be a pointer to a member variable.
Invoking such a bind expression returns a reference to the data member.
For example:
<pre class="programlisting">
struct A { int data; };
A a;
bind(&amp;A::data, _1)(a) = 1; // a.data == 1
</pre>
The cv-qualifiers of the object whose member is accessed are respected.
For example, the following tries to write into a const location:
<pre class="programlisting">
const A ca = a;
bind(&amp;A::data, _1)(ca) = 1; // error
</pre>
</p></div><div class="section"><div class="titlepage"><div><h4 class="title"><a name="sect:function_objects_as_targets"></a>5.3.4. Function objects as targets</h4></div></div><p>
</p></div><div class="section"><div class="titlepage"><div><h4 class="title"><a name="sect:function_objects_as_targets"></a>5.3.3. Function objects as targets</h4></div></div><p>
Function objects, that is, class objects which have the function call
operator defined, can be used as target functions.
@@ -746,7 +726,7 @@ 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
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>
</p><div class="simplesect"><div class="titlepage"><div><h5 class="title"><a name="id2792540"></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
<tt>sig&lt;Args&gt;</tt> with a typedef
@@ -968,7 +948,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="id2793385"></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 +977,7 @@ Here is an example of naming a delayed constant:
constant_type&lt;char&gt;::type space(constant(' '));
for_each(a.begin(),a.end(), cout &lt;&lt; space &lt;&lt; _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="id2793509"></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.
@@ -1284,7 +1264,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&lt;T&gt;()(<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.-&gt;A()</tt>, where <tt>pa</tt> is of type <tt>A*</tt></td></tr><tr><td><tt>new_ptr&lt;T&gt;()(<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&lt;T&gt;()(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&lt;T&gt;()(<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.-&gt;A()</tt>, where <tt>pa</tt> is of type <tt>A*</tt></td></tr><tr><td><tt>new_ptr&lt;T&gt;()(<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&lt;T&gt;()(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="id2794778"></a>5.9. Special lambda expressions</h3></div></div><div class="section"><div class="titlepage"><div><h4 class="title"><a name="id2794786"></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 +1390,7 @@ int nested(const F&amp; 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="id2795045"></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 +1495,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="id2795351"></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 +1524,7 @@ int count = 0;
for_each(a.begin(), a.end(),
if_then(ll_dynamic_cast&lt;derived*&gt;(_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="id2795453"></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 +1797,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&lt;plus_action&gt;</tt></td></tr><tr><td><tt>-</tt></td><td><tt>arithmetic_action&lt;minus_action&gt;</tt></td></tr><tr><td><tt>*</tt></td><td><tt>arithmetic_action&lt;multiply_action&gt;</tt></td></tr><tr><td><tt>/</tt></td><td><tt>arithmetic_action&lt;divide_action&gt;</tt></td></tr><tr><td><tt>%</tt></td><td><tt>arithmetic_action&lt;remainder_action&gt;</tt></td></tr><tr><td><tt>+</tt></td><td><tt>unary_arithmetic_action&lt;plus_action&gt;</tt></td></tr><tr><td><tt>-</tt></td><td><tt>unary_arithmetic_action&lt;minus_action&gt;</tt></td></tr><tr><td><tt>&amp;</tt></td><td><tt>bitwise_action&lt;and_action&gt;</tt></td></tr><tr><td><tt>|</tt></td><td><tt>bitwise_action&lt;or_action&gt;</tt></td></tr><tr><td><tt>~</tt></td><td><tt>bitwise_action&lt;not_action&gt;</tt></td></tr><tr><td><tt>^</tt></td><td><tt>bitwise_action&lt;xor_action&gt;</tt></td></tr><tr><td><tt>&lt;&lt;</tt></td><td><tt>bitwise_action&lt;leftshift_action_no_stream&gt;</tt></td></tr><tr><td><tt>&gt;&gt;</tt></td><td><tt>bitwise_action&lt;rightshift_action_no_stream&gt;</tt></td></tr><tr><td><tt>&amp;&amp;</tt></td><td><tt>logical_action&lt;and_action&gt;</tt></td></tr><tr><td><tt>||</tt></td><td><tt>logical_action&lt;or_action&gt;</tt></td></tr><tr><td><tt>!</tt></td><td><tt>logical_action&lt;not_action&gt;</tt></td></tr><tr><td><tt>&lt;</tt></td><td><tt>relational_action&lt;less_action&gt;</tt></td></tr><tr><td><tt>&gt;</tt></td><td><tt>relational_action&lt;greater_action&gt;</tt></td></tr><tr><td><tt>&lt;=</tt></td><td><tt>relational_action&lt;lessorequal_action&gt;</tt></td></tr><tr><td><tt>&gt;=</tt></td><td><tt>relational_action&lt;greaterorequal_action&gt;</tt></td></tr><tr><td><tt>==</tt></td><td><tt>relational_action&lt;equal_action&gt;</tt></td></tr><tr><td><tt>!=</tt></td><td><tt>relational_action&lt;notequal_action&gt;</tt></td></tr><tr><td><tt>+=</tt></td><td><tt>arithmetic_assignment_action&lt;plus_action&gt;</tt></td></tr><tr><td><tt>-=</tt></td><td><tt>arithmetic_assignment_action&lt;minus_action&gt;</tt></td></tr><tr><td><tt>*=</tt></td><td><tt>arithmetic_assignment_action&lt;multiply_action&gt;</tt></td></tr><tr><td><tt>/=</tt></td><td><tt>arithmetic_assignment_action&lt;divide_action&gt;</tt></td></tr><tr><td><tt>%=</tt></td><td><tt>arithmetic_assignment_action&lt;remainder_action&gt;</tt></td></tr><tr><td><tt>&amp;=</tt></td><td><tt>bitwise_assignment_action&lt;and_action&gt;</tt></td></tr><tr><td><tt>=|</tt></td><td><tt>bitwise_assignment_action&lt;or_action&gt;</tt></td></tr><tr><td><tt>^=</tt></td><td><tt>bitwise_assignment_action&lt;xor_action&gt;</tt></td></tr><tr><td><tt>&lt;&lt;=</tt></td><td><tt>bitwise_assignment_action&lt;leftshift_action&gt;</tt></td></tr><tr><td><tt>&gt;&gt;=</tt></td><td><tt>bitwise_assignment_action&lt;rightshift_action&gt;</tt></td></tr><tr><td><tt>++</tt></td><td><tt>pre_increment_decrement_action&lt;increment_action&gt;</tt></td></tr><tr><td><tt>--</tt></td><td><tt>pre_increment_decrement_action&lt;decrement_action&gt;</tt></td></tr><tr><td><tt>++</tt></td><td><tt>post_increment_decrement_action&lt;increment_action&gt;</tt></td></tr><tr><td><tt>--</tt></td><td><tt>post_increment_decrement_action&lt;decrement_action&gt;</tt></td></tr><tr><td><tt>&amp;</tt></td><td><tt>other_action&lt;address_of_action&gt;</tt></td></tr><tr><td><tt>*</tt></td><td><tt>other_action&lt;contents_of_action&gt;</tt></td></tr><tr><td><tt>,</tt></td><td><tt>other_action&lt;comma_action&gt;</tt></td></tr></tbody></table></div></div><div class="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&lt;plus_action&gt;</tt></td></tr><tr><td><tt>-</tt></td><td><tt>arithmetic_action&lt;minus_action&gt;</tt></td></tr><tr><td><tt>*</tt></td><td><tt>arithmetic_action&lt;multiply_action&gt;</tt></td></tr><tr><td><tt>/</tt></td><td><tt>arithmetic_action&lt;divide_action&gt;</tt></td></tr><tr><td><tt>%</tt></td><td><tt>arithmetic_action&lt;remainder_action&gt;</tt></td></tr><tr><td><tt>+</tt></td><td><tt>unary_arithmetic_action&lt;plus_action&gt;</tt></td></tr><tr><td><tt>-</tt></td><td><tt>unary_arithmetic_action&lt;minus_action&gt;</tt></td></tr><tr><td><tt>&amp;</tt></td><td><tt>bitwise_action&lt;and_action&gt;</tt></td></tr><tr><td><tt>|</tt></td><td><tt>bitwise_action&lt;or_action&gt;</tt></td></tr><tr><td><tt>~</tt></td><td><tt>bitwise_action&lt;not_action&gt;</tt></td></tr><tr><td><tt>^</tt></td><td><tt>bitwise_action&lt;xor_action&gt;</tt></td></tr><tr><td><tt>&lt;&lt;</tt></td><td><tt>bitwise_action&lt;leftshift_action_no_stream&gt;</tt></td></tr><tr><td><tt>&gt;&gt;</tt></td><td><tt>bitwise_action&lt;rightshift_action_no_stream&gt;</tt></td></tr><tr><td><tt>&amp;&amp;</tt></td><td><tt>logical_action&lt;and_action&gt;</tt></td></tr><tr><td><tt>||</tt></td><td><tt>logical_action&lt;or_action&gt;</tt></td></tr><tr><td><tt>!</tt></td><td><tt>logical_action&lt;not_action&gt;</tt></td></tr><tr><td><tt>&lt;</tt></td><td><tt>relational_action&lt;less_action&gt;</tt></td></tr><tr><td><tt>&gt;</tt></td><td><tt>relational_action&lt;greater_action&gt;</tt></td></tr><tr><td><tt>&lt;=</tt></td><td><tt>relational_action&lt;lessorequal_action&gt;</tt></td></tr><tr><td><tt>&gt;=</tt></td><td><tt>relational_action&lt;greaterorequal_action&gt;</tt></td></tr><tr><td><tt>==</tt></td><td><tt>relational_action&lt;equal_action&gt;</tt></td></tr><tr><td><tt>!=</tt></td><td><tt>relational_action&lt;notequal_action&gt;</tt></td></tr><tr><td><tt>+=</tt></td><td><tt>arithmetic_assignment_action&lt;plus_action&gt;</tt></td></tr><tr><td><tt>-=</tt></td><td><tt>arithmetic_assignment_action&lt;minus_action&gt;</tt></td></tr><tr><td><tt>*=</tt></td><td><tt>arithmetic_assignment_action&lt;multiply_action&gt;</tt></td></tr><tr><td><tt>/=</tt></td><td><tt>arithmetic_assignment_action&lt;divide_action&gt;</tt></td></tr><tr><td><tt>%=</tt></td><td><tt>arithmetic_assignment_action&lt;remainder_action&gt;</tt></td></tr><tr><td><tt>&amp;=</tt></td><td><tt>bitwise_assignment_action&lt;and_action&gt;</tt></td></tr><tr><td><tt>=|</tt></td><td><tt>bitwise_assignment_action&lt;or_action&gt;</tt></td></tr><tr><td><tt>^=</tt></td><td><tt>bitwise_assignment_action&lt;xor_action&gt;</tt></td></tr><tr><td><tt>&lt;&lt;=</tt></td><td><tt>bitwise_assignment_action&lt;leftshift_action&gt;</tt></td></tr><tr><td><tt>&gt;&gt;=</tt></td><td><tt>bitwise_assignment_action&lt;rightshift_action&gt;</tt></td></tr><tr><td><tt>++</tt></td><td><tt>pre_increment_decrement_action&lt;increment_action&gt;</tt></td></tr><tr><td><tt>--</tt></td><td><tt>pre_increment_decrement_action&lt;decrement_action&gt;</tt></td></tr><tr><td><tt>++</tt></td><td><tt>post_increment_decrement_action&lt;increment_action&gt;</tt></td></tr><tr><td><tt>--</tt></td><td><tt>post_increment_decrement_action&lt;decrement_action&gt;</tt></td></tr><tr><td><tt>&amp;</tt></td><td><tt>other_action&lt;address_of_action&gt;</tt></td></tr><tr><td><tt>*</tt></td><td><tt>other_action&lt;contents_of_action&gt;</tt></td></tr><tr><td><tt>,</tt></td><td><tt>other_action&lt;comma_action&gt;</tt></td></tr></tbody></table></div></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="id2796860"></a>7. Practical considerations</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2796866"></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.
@@ -1909,7 +1889,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="id2797359"></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.
@@ -1923,7 +1903,7 @@ This can make the error messages very long and difficult to interpret, particula
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="id2797420"></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 +1912,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="id2797460"></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 +1958,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="id2797804"></a>8. Relation to other Boost libraries</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2797812"></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.
@@ -2017,7 +1997,7 @@ 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="id2797916"></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 +2016,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="id2797980"></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 +2074,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="id2798095"></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 +2082,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="id2798117"></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,7 +2135,7 @@ 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="id2798269" class="bibliography"><div class="titlepage"><div><h2 class="title"><a name="id2798269"></a>Bibliography</h2></div></div><div class="biblioentry"><a name="cit:stepanov:94"></a><p>[STL94] <span class="authorgroup">A. A. Stepanov and M. Lee. </span><span class="title"><I>The Standard Template Library</I>. </span><span class="orgname">Hewlett-Packard Laboratories. </span><span class="pubdate">1994. </span><span class="bibliomisc">
<a href="http://www.hpl.hp.com/techreports" target="_top">www.hpl.hp.com/techreports</a>
. </span></p></div><div class="biblioentry"><a name="cit:sgi:02"></a><p>[SGI02] <span class="title"><I>The SGI Standard Template Library</I>. </span><span class="pubdate">2002. </span><span class="bibliomisc"><a href="http://www.sgi.com/tech/stl/" target="_top">www.sgi.com/tech/stl/</a>. </span></p></div><div class="biblioentry"><a name="cit:c++:98"></a><p>[C++98] <span class="title"><I>International Standard, Programming Languages &#8211; C++</I>. </span><span class="subtitle">ISO/IEC:14882. </span><span class="pubdate">1998. </span></p></div><div class="biblioentry"><a name="cit:jarvi:99"></a><p>[Jär99] <span class="articleinfo">
<span class="author">Jaakko Järvi. </span>
@@ -2166,7 +2146,7 @@ was dropped.
. </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.id2729011" href="#id2729011">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.

View File

@@ -91,7 +91,7 @@ public:
// return types of casting lambda_functors (all "T" type.)
template<template <class> class cast_type, class T, class A>
template<template <class T> class cast_type, class T, class A>
struct return_type_N<cast_action< cast_type<T> >, A> {
typedef T type;
};

View File

@@ -39,7 +39,7 @@ public:
: lambda_functor<Args>(a) {}
// for the no body cases in control structures.
tagged_lambda_functor() : lambda_functor<Args>() {}
explicit tagged_lambda_functor() : lambda_functor<Args>( null_type() ) {}
};
} // lambda

View File

@@ -24,18 +24,8 @@ namespace lambda {
template <class Func> struct function_adaptor {
// we do not know the return type off-hand, we must ask it from Func
template <class Args> class sig {
typedef typename Args::head_type F;
typedef typename detail::remove_reference_and_cv<Func>::type plainF;
public:
// To sig we pass a cons list, where the head is the function object type
// itself (potentially cv-qualified)
// and the tail contains the types of the actual arguments to be passed
// to the function object. The arguments can be cv qualified
// as well.
typedef typename plainF::template sig<Args>::type type;
};
typedef detail::unspecified type;
template <class T> struct sig { typedef detail::unspecified type; };
template<class RET, class A1>
static RET apply(A1& a1) {
@@ -89,74 +79,11 @@ template <class Func> struct function_adaptor {
template <class Func> struct function_adaptor<const Func>; // error
// -- function adaptors with data member access
template <class Object, class T>
struct function_adaptor<T Object::*> {
// typedef detail::unspecified type;
// T can have qualifiers and can be a reference type
// We get the return type by adding const, if the object through which
// the data member is accessed is const, and finally adding a reference
template<class Args> class sig {
typedef typename boost::tuples::element<1, Args>::type argument_type;
typedef typename detail::IF<boost::is_const<argument_type>::value,
typename boost::add_const<T>::type,
T
>::RET properly_consted_return_type;
typedef typename detail::IF<
boost::is_volatile<properly_consted_return_type>::value,
typename boost::add_volatile<properly_consted_return_type>::type,
properly_consted_return_type
>::RET properly_cvd_return_type;
public:
typedef typename
boost::add_reference<properly_cvd_return_type>::type type;
};
template <class RET>
static RET apply( T Object::*data, Object& o) {
return o.*data;
}
template <class RET>
static RET apply( T Object::*data, const Object& o) {
return o.*data;
}
template <class RET>
static RET apply( T Object::*data, volatile Object& o) {
return o.*data;
}
template <class RET>
static RET apply( T Object::*data, const volatile Object& o) {
return o.*data;
}
template <class RET>
static RET apply( T Object::*data, Object* o) {
return o->*data;
}
template <class RET>
static RET apply( T Object::*data, const Object* o) {
return o->*data;
}
template <class RET>
static RET apply( T Object::*data, volatile Object* o) {
return o->*data;
}
template <class RET>
static RET apply( T Object::*data, const volatile Object* o) {
return o->*data;
}
};
// -- function adaptors with 1 argument apply
template <class Result>
struct function_adaptor<Result (void)> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET>
static Result apply(Result (*func)()) {
@@ -166,7 +93,7 @@ struct function_adaptor<Result (void)> {
template <class Result>
struct function_adaptor<Result (*)(void)> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET>
static Result apply(Result (*func)()) {
@@ -178,7 +105,7 @@ struct function_adaptor<Result (*)(void)> {
// -- function adaptors with 2 argument apply
template <class Object, class Result>
struct function_adaptor<Result (Object::*)() const> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET>
static Result apply( Result (Object::*func)() const, const Object* o) {
@@ -192,7 +119,7 @@ struct function_adaptor<Result (Object::*)() const> {
template <class Object, class Result>
struct function_adaptor<Result (Object::*)()> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET>
static Result apply( Result (Object::*func)(), Object* o) {
@@ -206,7 +133,7 @@ struct function_adaptor<Result (Object::*)()> {
template <class Arg1, class Result>
struct function_adaptor<Result (Arg1)> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET, class A1>
static Result apply(Result (*func)(Arg1), A1& a1) {
@@ -216,7 +143,7 @@ struct function_adaptor<Result (Arg1)> {
template <class Arg1, class Result>
struct function_adaptor<Result (*)(Arg1)> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET, class A1>
static Result apply(Result (*func)(Arg1), A1& a1) {
@@ -228,7 +155,7 @@ struct function_adaptor<Result (*)(Arg1)> {
// -- function adaptors with 3 argument apply
template <class Object, class Arg1, class Result>
struct function_adaptor<Result (Object::*)(Arg1) const> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET, class A1>
static Result apply( Result (Object::*func)(Arg1) const, const Object* o,
@@ -244,7 +171,7 @@ struct function_adaptor<Result (Object::*)(Arg1) const> {
template <class Object, class Arg1, class Result>
struct function_adaptor<Result (Object::*)(Arg1)> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET, class A1>
static Result apply( Result (Object::*func)(Arg1), Object* o, A1& a1) {
@@ -258,7 +185,7 @@ struct function_adaptor<Result (Object::*)(Arg1)> {
template <class Arg1, class Arg2, class Result>
struct function_adaptor<Result (Arg1, Arg2)> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2>
static Result apply(Result (*func)(Arg1, Arg2), A1& a1, A2& a2) {
@@ -268,7 +195,7 @@ struct function_adaptor<Result (Arg1, Arg2)> {
template <class Arg1, class Arg2, class Result>
struct function_adaptor<Result (*)(Arg1, Arg2)> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2>
static Result apply(Result (*func)(Arg1, Arg2), A1& a1, A2& a2) {
@@ -280,7 +207,7 @@ struct function_adaptor<Result (*)(Arg1, Arg2)> {
// -- function adaptors with 4 argument apply
template <class Object, class Arg1, class Arg2, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2) const> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2>
static Result apply( Result (Object::*func)(Arg1, Arg2) const, const Object* o, A1& a1, A2& a2) {
@@ -294,7 +221,7 @@ struct function_adaptor<Result (Object::*)(Arg1, Arg2) const> {
template <class Object, class Arg1, class Arg2, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2)> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2>
static Result apply( Result (Object::*func)(Arg1, Arg2), Object* o, A1& a1, A2& a2) {
@@ -308,7 +235,7 @@ struct function_adaptor<Result (Object::*)(Arg1, Arg2)> {
template <class Arg1, class Arg2, class Arg3, class Result>
struct function_adaptor<Result (Arg1, Arg2, Arg3)> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3>
static Result apply(Result (*func)(Arg1, Arg2, Arg3), A1& a1, A2& a2, A3& a3) {
@@ -318,7 +245,7 @@ struct function_adaptor<Result (Arg1, Arg2, Arg3)> {
template <class Arg1, class Arg2, class Arg3, class Result>
struct function_adaptor<Result (*)(Arg1, Arg2, Arg3)> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3>
static Result apply(Result (*func)(Arg1, Arg2, Arg3), A1& a1, A2& a2, A3& a3) {
@@ -330,7 +257,7 @@ struct function_adaptor<Result (*)(Arg1, Arg2, Arg3)> {
// -- function adaptors with 5 argument apply
template <class Object, class Arg1, class Arg2, class Arg3, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3) const> {
typedef Result type;
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) const, const Object* o, A1& a1, A2& a2, A3& a3) {
@@ -344,7 +271,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)> {
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);
@@ -357,7 +284,7 @@ struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3)> {
template <class Arg1, class Arg2, class Arg3, class Arg4, class Result>
struct function_adaptor<Result (Arg1, Arg2, Arg3, Arg4)> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4>
static Result apply(Result (*func)(Arg1, Arg2, Arg3, Arg4), A1& a1, A2& a2, A3& a3, A4& a4) {
@@ -367,7 +294,7 @@ struct function_adaptor<Result (Arg1, Arg2, Arg3, Arg4)> {
template <class Arg1, class Arg2, class Arg3, class Arg4, class Result>
struct function_adaptor<Result (*)(Arg1, Arg2, Arg3, Arg4)> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4>
static Result apply(Result (*func)(Arg1, Arg2, Arg3, Arg4), A1& a1, A2& a2, A3& a3, A4& a4) {
@@ -379,7 +306,7 @@ struct function_adaptor<Result (*)(Arg1, Arg2, Arg3, Arg4)> {
// -- function adaptors with 6 argument apply
template <class Object, class Arg1, class Arg2, class Arg3, class Arg4, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4) const> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4) const, const Object* o, A1& a1, A2& a2, A3& a3, A4& a4) {
@@ -393,7 +320,7 @@ struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4) const> {
template <class Object, class Arg1, class Arg2, class Arg3, class Arg4, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4)> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4), Object* o, A1& a1, A2& a2, A3& a3, A4& a4) {
@@ -407,7 +334,7 @@ struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4)> {
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Result>
struct function_adaptor<Result (Arg1, Arg2, Arg3, Arg4, Arg5)> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5>
static Result apply(Result (*func)(Arg1, Arg2, Arg3, Arg4, Arg5), A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) {
@@ -417,7 +344,7 @@ struct function_adaptor<Result (Arg1, Arg2, Arg3, Arg4, Arg5)> {
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Result>
struct function_adaptor<Result (*)(Arg1, Arg2, Arg3, Arg4, Arg5)> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5>
static Result apply(Result (*func)(Arg1, Arg2, Arg3, Arg4, Arg5), A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) {
@@ -429,7 +356,7 @@ struct function_adaptor<Result (*)(Arg1, Arg2, Arg3, Arg4, Arg5)> {
// -- function adaptors with 7 argument apply
template <class Object, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5) const> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5) const, const Object* o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) {
@@ -443,7 +370,7 @@ struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5) const>
template <class Object, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5)> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5), Object* o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) {
@@ -457,7 +384,7 @@ struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5)> {
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Result>
struct function_adaptor<Result (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6>
static Result apply(Result (*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6), A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6) {
@@ -467,7 +394,7 @@ struct function_adaptor<Result (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)> {
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Result>
struct function_adaptor<Result (*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6>
static Result apply(Result (*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6), A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6) {
@@ -479,7 +406,7 @@ struct function_adaptor<Result (*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)> {
// -- function adaptors with 8 argument apply
template <class Object, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) const> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) const, const Object* o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6) {
@@ -493,7 +420,7 @@ struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) c
template <class Object, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)> {
typedef Result type;
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6), Object* o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6) {
@@ -507,7 +434,7 @@ struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)>
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Result>
struct function_adaptor<Result (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)> {
typedef Result type;
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>
static Result apply(Result (*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7), A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7) {
@@ -517,7 +444,7 @@ struct function_adaptor<Result (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)> {
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Result>
struct function_adaptor<Result (*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)> {
typedef Result type;
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>
static Result apply(Result (*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7), A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7) {
@@ -529,7 +456,7 @@ struct function_adaptor<Result (*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)> {
// -- function adaptors with 9 argument apply
template <class Object, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) const> {
typedef Result type;
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>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) const, const Object* o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7) {
@@ -543,7 +470,7 @@ struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, A
template <class Object, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)> {
typedef Result type;
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>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7), Object* o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7) {
@@ -557,7 +484,7 @@ struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, A
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8, class Result>
struct function_adaptor<Result (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8)> {
typedef Result type;
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>
static Result apply(Result (*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8), A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8) {
@@ -567,7 +494,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 Result>
struct function_adaptor<Result (*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8)> {
typedef Result type;
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>
static Result apply(Result (*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8), A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8) {
@@ -579,7 +506,7 @@ struct function_adaptor<Result (*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg
// -- function adaptors with 10 argument apply
template <class Object, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) const> {
typedef Result type;
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>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) const, const Object* o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8) {
@@ -593,7 +520,7 @@ struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, A
template <class Object, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8)> {
typedef Result type;
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>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8), Object* o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8) {
@@ -607,7 +534,7 @@ struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, A
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)> {
typedef Result type;
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) {
@@ -617,13 +544,54 @@ 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)> {
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);
}
};
namespace detail {
template <class Args> class get_sig_result_type {
typedef typename Args::head_type Func;
typedef typename detail::remove_reference_and_cv<Func>::type plainF;
public:
// To sig we pass a cons list, where the head is the function object type
// itself (potentially cv-qualified)
// and the tail contains the types of the actual arguments to be passed
// to the function object. The arguments can be cv qualified
// as well.
typedef typename plainF::template sig<Args>::type type;
};
} // end detail
template <class Args>
class function_adaptor_with_actuals
{
typedef typename Args::head_type Func;
typedef typename detail::remove_reference_and_cv<Func>::type plain_Func;
// get the return type from the function adaptor class
// this succeeds for func.pointers, member functions etc.
typedef typename function_adaptor<plain_Func>::type type1;
public:
// if we get unspecified, Func is a function object class
// thus it is ok to try the sig template
typedef typename
detail::IF_type<
boost::is_same<type1, detail::unspecified>::value,
detail::get_sig_result_type<Args>,
function_adaptor<plain_Func>
>::type type;
};
} // namespace lambda
} // namespace boost

View File

@@ -310,9 +310,7 @@ template<class Args>
class lambda_functor_base<do_nothing_action, Args> {
// Args args;
public:
// explicit lambda_functor_base(const Args& a) {}
lambda_functor_base() {}
explicit lambda_functor_base(const Args& a) {}
template<class RET, CALL_TEMPLATE_ARGS> RET call(CALL_FORMAL_ARGS) const {
CALL_USE_ARGS;

View File

@@ -291,7 +291,7 @@ lambda_functor<
>
make_void(const Arg1& a1) {
return
lambda_functor_base<do_nothing_action, null_type>();
lambda_functor_base<do_nothing_action, null_type>(null_type());
}
// std_functor -----------------------------------------------------

View File

@@ -242,16 +242,7 @@ struct return_type_N<function_action<I, Ret>, Args> {
// 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 > {
// in the case of function action, the first element in Args is
// some type of function
typedef typename Args::head_type Func;
typedef typename detail::remove_reference_and_cv<Func>::type plain_Func;
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 function_adaptor_with_actuals<Args>::type type;
};

View File

@@ -30,16 +30,16 @@ inline Any& select(Any& any, CALL_FORMAL_ARGS) { CALL_USE_ARGS; return any; }
template<class Arg, CALL_TEMPLATE_ARGS>
inline typename Arg::template sig<tuple<CALL_REFERENCE_TYPES> >::type
select ( const lambda_functor<Arg>& op, CALL_FORMAL_ARGS ) {
return op.template call<
typename Arg::template sig<tuple<CALL_REFERENCE_TYPES> >::type
>(CALL_ACTUAL_ARGS);
return op.template call<
typename Arg::template sig<tuple<CALL_REFERENCE_TYPES> >::type
>(CALL_ACTUAL_ARGS);
}
template<class Arg, CALL_TEMPLATE_ARGS>
inline typename Arg::template sig<tuple<CALL_REFERENCE_TYPES> >::type
select ( lambda_functor<Arg>& op, CALL_FORMAL_ARGS) {
return op.template call<
typename Arg::template sig<tuple<CALL_REFERENCE_TYPES> >::type
>(CALL_ACTUAL_ARGS);
return op.template call<
typename Arg::template sig<tuple<CALL_REFERENCE_TYPES> >::type
>(CALL_ACTUAL_ARGS);
}
// ------------------------------------------------------------------------

View File

@@ -307,7 +307,7 @@ catch_exception(const lambda_functor<Arg>& a) {
}
// catch and do nothing case.
template <class CatchType>
template <class CatchType, class Arg>
inline const
tagged_lambda_functor<
detail::exception_catch_tag<detail::catch_block<CatchType> >,
@@ -328,7 +328,7 @@ catch_exception() {
null_type
>
>
> ();
> (null_type());
}
// create catch(...) blocks
@@ -349,6 +349,7 @@ catch_all(const lambda_functor<Arg>& a) {
}
// catch(...) and do nothing case.
template <class CatchType, class Arg>
inline const
tagged_lambda_functor<
detail::exception_catch_tag<detail::catch_all_block>,
@@ -369,7 +370,7 @@ catch_all() {
null_type
>
>
> ();
> (null_type());
}
// try_catch functions --------------------------------

View File

@@ -129,7 +129,7 @@ return
lambda_functor_base<
do_nothing_action,
null_type
> () ;
> (cnull_type()) ;
}
@@ -392,7 +392,7 @@ switch_statement() {
do_nothing_action,
null_type
>
();
( null_type());
}
// 1 argument case, this is useless as well, just the condition part

View File

@@ -512,19 +512,6 @@ void test_different_number_of_catch_blocks() {
BOOST_TEST(ecount == 9);
}
void test_empty_catch_blocks() {
try_catch(
bind(throw_AX, _1),
catch_exception<A1>()
)(make_const(1));
try_catch(
bind(throw_AX, _1),
catch_all()
)(make_const(1));
}
void return_type_matching() {
@@ -589,7 +576,6 @@ int test_main(int, char *[]) {
{
test_different_number_of_catch_blocks();
return_type_matching();
test_empty_catch_blocks();
}
catch (int x)
{

View File

@@ -95,7 +95,7 @@ void bitwise_operators() {
BOOST_TEST((_1 & 1)(ui)==(2 & 1));
BOOST_TEST((_1 | 1)(ui)==(2 | 1));
BOOST_TEST((_1 ^ 1)(ui)==(2 ^ 1));
BOOST_TEST((~_1)(ui)==~2u);
BOOST_TEST((~_1)(ui)==~2);
}
void comparison_operators() {

View File

@@ -351,30 +351,11 @@ void do_switch_yes_defaults_tests() {
}
void test_empty_cases() {
using namespace boost::lambda;
// ---
switch_statement(
_1,
default_statement()
)(make_const(1));
switch_statement(
_1,
case_statement<1>()
)(make_const(1));
}
int test_main(int, char* []) {
do_switch_no_defaults_tests();
do_switch_yes_defaults_tests();
test_empty_cases();
return EXIT_SUCCESS;
}