]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/local_function/doc/html/boost_localfunction/alternatives.html
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / local_function / doc / html / boost_localfunction / alternatives.html
1 <html>
2 <head>
3 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
4 <title>Annex: Alternatives</title>
5 <link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
6 <meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
7 <link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Boost.LocalFunction 1.0.0">
8 <link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.LocalFunction 1.0.0">
9 <link rel="prev" href="examples.html" title="Examples">
10 <link rel="next" href="no_variadic_macros.html" title="Annex: No Variadic Macros">
11 </head>
12 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13 <table cellpadding="2" width="100%"><tr>
14 <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
15 <td align="center"><a href="../../../../../index.html">Home</a></td>
16 <td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
17 <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
18 <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
19 <td align="center"><a href="../../../../../more/index.htm">More</a></td>
20 </tr></table>
21 <hr>
22 <div class="spirit-nav">
23 <a accesskey="p" href="examples.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="no_variadic_macros.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
24 </div>
25 <div class="section">
26 <div class="titlepage"><div><div><h2 class="title" style="clear: both">
27 <a name="boost_localfunction.alternatives"></a><a class="link" href="alternatives.html" title="Annex: Alternatives">Annex: Alternatives</a>
28 </h2></div></div></div>
29 <p>
30 This section compares the features offered by this library with similar features
31 offered by C++ and by other libraries.
32 </p>
33 <h4>
34 <a name="boost_localfunction.alternatives.h0"></a>
35 <span class="phrase"><a name="boost_localfunction.alternatives.features"></a></span><a class="link" href="alternatives.html#boost_localfunction.alternatives.features">Features</a>
36 </h4>
37 <p>
38 The following table compares local function features.
39 </p>
40 <div class="informaltable"><table class="table">
41 <colgroup>
42 <col>
43 <col>
44 <col>
45 <col>
46 <col>
47 <col>
48 </colgroup>
49 <thead><tr>
50 <th>
51 <p>
52 Local Function Feature
53 </p>
54 </th>
55 <th>
56 <p>
57 Boost.LocalFunction
58 </p>
59 </th>
60 <th>
61 <p>
62 C++11 Lambda Function (Not C++03)
63 </p>
64 </th>
65 <th>
66 <p>
67 Local Functor
68 </p>
69 </th>
70 <th>
71 <p>
72 Global Functor (Not Local)
73 </p>
74 </th>
75 <th>
76 <p>
77 Boost.Phoenix
78 </p>
79 </th>
80 </tr></thead>
81 <tbody>
82 <tr>
83 <td>
84 <p>
85 <span class="emphasis"><em>Can be defined locally</em></span>
86 </p>
87 </td>
88 <td>
89 <p>
90 Yes.
91 </p>
92 </td>
93 <td>
94 <p>
95 Yes.
96 </p>
97 </td>
98 <td>
99 <p>
100 Yes.
101 </p>
102 </td>
103 <td>
104 <p>
105 No. Therefore this not really an alternative implementation of local
106 functions but it is listed here just for comparison.
107 </p>
108 </td>
109 <td>
110 <p>
111 Yes.
112 </p>
113 </td>
114 </tr>
115 <tr>
116 <td>
117 <p>
118 <span class="emphasis"><em>Can be defined using C++ statement syntax</em></span>
119 </p>
120 </td>
121 <td>
122 <p>
123 Yes. Plus eventual compiler errors and debugging retain their usual
124 meaning and format.
125 </p>
126 </td>
127 <td>
128 <p>
129 Yes. Plus eventual compiler errors and debugging retain their usual
130 meaning and format.
131 </p>
132 </td>
133 <td>
134 <p>
135 Yes. Plus eventual compiler errors and debugging retain their usual
136 meaning and format.
137 </p>
138 </td>
139 <td>
140 <p>
141 Yes. Plus eventual compiler errors and debugging retain their usual
142 meaning and format.
143 </p>
144 </td>
145 <td>
146 <p>
147 No (it uses C++ <a href="http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Expression-template" target="_top">expression
148 template</a> syntax).
149 </p>
150 </td>
151 </tr>
152 <tr>
153 <td>
154 <p>
155 <span class="emphasis"><em>Can be defined within expressions</em></span>
156 </p>
157 </td>
158 <td>
159 <p>
160 No. It can be defined only within declarations.
161 </p>
162 </td>
163 <td>
164 <p>
165 Yes (plus the local function can be unnamed).
166 </p>
167 </td>
168 <td>
169 <p>
170 No. It can be defined only within declarations.
171 </p>
172 </td>
173 <td>
174 <p>
175 No. It can be defined only within declarations.
176 </p>
177 </td>
178 <td>
179 <p>
180 Yes (plus the local function can be unnamed).
181 </p>
182 </td>
183 </tr>
184 <tr>
185 <td>
186 <p>
187 <span class="emphasis"><em>Can be passed as template parameter (e.g., to STL algorithms)</em></span>
188 </p>
189 </td>
190 <td>
191 <p>
192 Yes. The <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a>
193 standard does not allow to pass local types as template parameters
194 (see <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm" target="_top">[N2657]</a>)
195 but this library implements a "trick" to get around this
196 limitation (see the <a class="link" href="implementation.html" title="Annex: Implementation">Implementation</a>
197 section).
198 </p>
199 </td>
200 <td>
201 <p>
202 Yes.
203 </p>
204 </td>
205 <td>
206 <p>
207 No on <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a>
208 compilers (but yes on <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a>
209 compilers and some compilers like MSVC 8.0, see <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm" target="_top">[N2657]</a>).
210 </p>
211 </td>
212 <td>
213 <p>
214 Yes.
215 </p>
216 </td>
217 <td>
218 <p>
219 Yes.
220 </p>
221 </td>
222 </tr>
223 <tr>
224 <td>
225 <p>
226 <span class="emphasis"><em>Access variables in scope</em></span>
227 </p>
228 </td>
229 <td>
230 <p>
231 Yes. The variable names are repeated in the function declaration
232 so they can be bound by value, by constant value, by reference, and
233 by constant reference (the object <code class="computeroutput"><span class="keyword">this</span></code>
234 can also be bound using <code class="computeroutput"><span class="identifier">this_</span></code>).
235 </p>
236 </td>
237 <td>
238 <p>
239 Yes. The variable names are repeated in the function declaration
240 (plus there is a short-hand syntax to bind all variables in scope
241 at once) so they can be bound by constant value and by reference
242 (the object <code class="computeroutput"><span class="keyword">this</span></code> can
243 also be bound). However, variables cannot be bound by constant references
244 (see below).
245 </p>
246 </td>
247 <td>
248 <p>
249 No. Programmers must manually program functor data members and explicitly
250 specify their types to access variables in scope.
251 </p>
252 </td>
253 <td>
254 <p>
255 No. Programmers must manually program functor data members and explicitly
256 specify their types to access variables in scope.
257 </p>
258 </td>
259 <td>
260 <p>
261 Yes. Variables in scope are accessible as usual within expressions
262 (plus <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">let</span></code> can be used to bind variables
263 by constant reference).
264 </p>
265 </td>
266 </tr>
267 <tr>
268 <td>
269 <p>
270 <span class="emphasis"><em><a href="http://en.wikipedia.org/wiki/Type_polymorphism#Parametric_polymorphism" target="_top">Polymorphic</a>
271 in the function parameter type</em></span>
272 </p>
273 </td>
274 <td>
275 <p>
276 No (local functions cannot be function templates).
277 </p>
278 </td>
279 <td>
280 <p>
281 No (<a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a>
282 lambdas cannot be function templates).
283 </p>
284 </td>
285 <td>
286 <p>
287 No (local classes cannot have member function templates).
288 </p>
289 </td>
290 <td>
291 <p>
292 Yes.
293 </p>
294 </td>
295 <td>
296 <p>
297 Yes.
298 </p>
299 </td>
300 </tr>
301 </tbody>
302 </table></div>
303 <p>
304 <span class="bold"><strong>C++11 Lambda Function</strong></span>
305 </p>
306 <p>
307 <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11
308 lambda functions</a> have most of the features of this library plus some
309 additional feature (see also the example in the <a class="link" href="../index.html#boost_localfunction.introduction" title="Introduction">Introduction</a>
310 section):
311 </p>
312 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
313 <li class="listitem">
314 <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11
315 lambda functions</a> can be defined within expressions while this library
316 local functions can only be defined at declaration scope.
317 </li>
318 <li class="listitem">
319 <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11
320 lambda functions</a> are only supported by the <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a>
321 standard so they are not supported by all C++ compilers. This library local
322 functions can be programmed also on <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a>
323 compilers (and they have performances comparable to <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11
324 lambda functions</a> on <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a>
325 compilers).
326 </li>
327 <li class="listitem">
328 <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11
329 lambda functions</a> do not allow to bind variables in scope by constant
330 reference. Because a variable cannot be bound by constant reference, <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11
331 lambda functions</a> can bind a variable by constant only if the variable
332 is <code class="computeroutput"><span class="identifier">CopyConstructible</span></code> and
333 the binding requires a (potentially expensive) extra copy operation. Constant
334 reference binding is instead supported by this library.
335 </li>
336 <li class="listitem">
337 <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11
338 lambda functions</a> do not allow to bind data members selectively
339 without binding also the object <code class="computeroutput"><span class="keyword">this</span></code>
340 while this library local functions can bind either selected data members
341 or the entire object <code class="computeroutput"><span class="keyword">this</span></code>
342 (using <code class="computeroutput"><span class="identifier">this_</span></code>).
343 </li>
344 <li class="listitem">
345 <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11
346 lambda functions</a> provide a short-hand syntax to bind all variables
347 in scope at once (<code class="computeroutput"><span class="special">&amp;</span></code> or
348 <code class="computeroutput"><span class="special">=</span></code>) while this library local
349 function always require to bind variables naming them one-by-one.
350 </li>
351 </ul></div>
352 <p>
353 For example, for non-copyable objects (see also <a href="../../../example/noncopyable_cxx11_lambda_error.cpp" target="_top"><code class="literal">noncopyable_cxx11_lambda_error.cpp</code></a>
354 and <a href="../../../example/noncopyable_local_function.cpp" target="_top"><code class="literal">noncopyable_local_function.cpp</code></a>):
355 </p>
356 <div class="informaltable"><table class="table">
357 <colgroup>
358 <col>
359 <col>
360 </colgroup>
361 <thead><tr>
362 <th>
363 <p>
364 C++11 Lambda Function
365 </p>
366 </th>
367 <th>
368 <p>
369 Boost.LocalFunction
370 </p>
371 </th>
372 </tr></thead>
373 <tbody><tr>
374 <td>
375 <p>
376 </p>
377 <pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">struct</span> <span class="identifier">n</span><span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">noncopyable</span> <span class="special">{</span>
378 <span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span>
379 <span class="identifier">n</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">_i</span><span class="special">):</span> <span class="identifier">i</span><span class="special">(</span><span class="identifier">_i</span><span class="special">)</span> <span class="special">{}</span>
380 <span class="special">};</span>
381
382
383 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span>
384 <span class="identifier">n</span> <span class="identifier">x</span><span class="special">(-</span><span class="number">1</span><span class="special">);</span>
385
386 <span class="keyword">auto</span> <span class="identifier">f</span> <span class="special">=</span> <span class="special">[</span><span class="identifier">x</span><span class="special">](</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Error: x is non-copyable, but if</span>
387 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">i</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span> <span class="comment">// bind `&amp;x` then `x` is not constant.</span>
388 <span class="special">};</span>
389 <span class="identifier">f</span><span class="special">();</span>
390
391 <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
392 <span class="special">}</span>
393 </pre>
394 <p>
395 </p>
396 </td>
397 <td>
398 <p>
399 </p>
400 <pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">struct</span> <span class="identifier">n</span><span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">noncopyable</span> <span class="special">{</span>
401 <span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span>
402 <span class="identifier">n</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">_i</span><span class="special">):</span> <span class="identifier">i</span><span class="special">(</span><span class="identifier">_i</span><span class="special">)</span> <span class="special">{}</span>
403 <span class="special">};</span>
404 <span class="identifier">BOOST_TYPEOF_REGISTER_TYPE</span><span class="special">(</span><span class="identifier">n</span><span class="special">)</span> <span class="comment">// Register for `bind&amp; x` below.</span>
405
406 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span>
407 <span class="identifier">n</span> <span class="identifier">x</span><span class="special">(-</span><span class="number">1</span><span class="special">);</span>
408
409 <span class="keyword">void</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">bind</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// OK: No copy</span>
410 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">i</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span> <span class="comment">// and constant.</span>
411 <span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">f</span><span class="special">)</span>
412 <span class="identifier">f</span><span class="special">();</span>
413
414 <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
415 <span class="special">}</span>
416 </pre>
417 <p>
418 </p>
419 </td>
420 </tr></tbody>
421 </table></div>
422 <p>
423 Or, for objects with expensive copy operations (see also <a href="../../../example/expensive_copy_cxx11_lambda.cpp" target="_top"><code class="literal">expensive_copy_cxx11_lambda.cpp</code></a>
424 and <a href="../../../example/expensive_copy_local_function.cpp" target="_top"><code class="literal">expensive_copy_local_function.cpp</code></a>):
425 </p>
426 <div class="informaltable"><table class="table">
427 <colgroup>
428 <col>
429 <col>
430 </colgroup>
431 <thead><tr>
432 <th>
433 <p>
434 C++11 Lambda Function
435 </p>
436 </th>
437 <th>
438 <p>
439 Boost.LocalFunction
440 </p>
441 </th>
442 </tr></thead>
443 <tbody><tr>
444 <td>
445 <p>
446 </p>
447 <pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">struct</span> <span class="identifier">n</span> <span class="special">{</span>
448 <span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span>
449 <span class="identifier">n</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">_i</span><span class="special">):</span> <span class="identifier">i</span><span class="special">(</span><span class="identifier">_i</span><span class="special">)</span> <span class="special">{}</span>
450 <span class="identifier">n</span><span class="special">(</span><span class="identifier">n</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">):</span> <span class="identifier">i</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">i</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Some time consuming copy operation.</span>
451 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="number">10000</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="char">'.'</span><span class="special">;</span>
452 <span class="special">}</span>
453 <span class="special">};</span>
454
455
456 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span>
457 <span class="identifier">n</span> <span class="identifier">x</span><span class="special">(-</span><span class="number">1</span><span class="special">);</span>
458
459 <span class="keyword">auto</span> <span class="identifier">f</span> <span class="special">=</span> <span class="special">[</span><span class="identifier">x</span><span class="special">]()</span> <span class="special">{</span> <span class="comment">// Problem: Expensive copy, but if bind</span>
460 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">i</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span> <span class="comment">// by `&amp;x` then `x` is not constant.</span>
461 <span class="special">};</span>
462 <span class="identifier">f</span><span class="special">();</span>
463
464 <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
465 <span class="special">}</span>
466 </pre>
467 <p>
468 </p>
469 </td>
470 <td>
471 <p>
472 </p>
473 <pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">struct</span> <span class="identifier">n</span> <span class="special">{</span>
474 <span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span>
475 <span class="identifier">n</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">_i</span><span class="special">):</span> <span class="identifier">i</span><span class="special">(</span><span class="identifier">_i</span><span class="special">)</span> <span class="special">{}</span>
476 <span class="identifier">n</span><span class="special">(</span><span class="identifier">n</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">):</span> <span class="identifier">i</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">i</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Some time consuming copy operation.</span>
477 <span class="keyword">for</span> <span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="number">10000</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="char">'.'</span><span class="special">;</span>
478 <span class="special">}</span>
479 <span class="special">};</span>
480 <span class="identifier">BOOST_TYPEOF_REGISTER_TYPE</span><span class="special">(</span><span class="identifier">n</span><span class="special">)</span> <span class="comment">// Register for `bind&amp; x` below.</span>
481
482 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span>
483 <span class="identifier">n</span> <span class="identifier">x</span><span class="special">(-</span><span class="number">1</span><span class="special">);</span>
484
485 <span class="keyword">void</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">bind</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// OK: No copy expensive</span>
486 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">i</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span> <span class="comment">// copy but constant.</span>
487 <span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">f</span><span class="special">)</span>
488 <span class="identifier">f</span><span class="special">();</span>
489
490 <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
491 <span class="special">}</span>
492 </pre>
493 <p>
494 </p>
495 </td>
496 </tr></tbody>
497 </table></div>
498 <p>
499 When constant binding functionality is needed for <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11
500 lambda functions</a>, the best alternative might be to bind an extra local
501 variable declared constant and initialized to the original variable (for example,
502 see <span class="emphasis"><em>constant blocks</em></span> implemented with <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11
503 lambda functions</a> in the <a class="link" href="examples.html" title="Examples">Examples</a>
504 section).
505 </p>
506 <p>
507 <span class="bold"><strong>Local Functor</strong></span>
508 </p>
509 <p>
510 The following example compares local functions with C++ local functors (see
511 also <a href="../../../example/add_local_functor.cpp" target="_top"><code class="literal">add_local_functor.cpp</code></a>
512 and <a href="../../../test/add.cpp" target="_top"><code class="literal">add.cpp</code></a>):
513 </p>
514 <div class="informaltable"><table class="table">
515 <colgroup>
516 <col>
517 <col>
518 </colgroup>
519 <thead><tr>
520 <th>
521 <p>
522 Local Functor
523 </p>
524 </th>
525 <th>
526 <p>
527 Boost.LocalFunction
528 </p>
529 </th>
530 </tr></thead>
531 <tbody><tr>
532 <td>
533 <p>
534 </p>
535 <pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span>
536 <span class="keyword">int</span> <span class="identifier">sum</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">factor</span> <span class="special">=</span> <span class="number">10</span><span class="special">;</span>
537
538 <span class="keyword">struct</span> <span class="identifier">local_add</span> <span class="special">{</span> <span class="comment">// Unfortunately, boilerplate code to program the class.</span>
539 <span class="identifier">local_add</span><span class="special">(</span><span class="keyword">int</span><span class="special">&amp;</span> <span class="identifier">_sum</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">_factor</span><span class="special">):</span> <span class="identifier">sum</span><span class="special">(</span><span class="identifier">_sum</span><span class="special">),</span> <span class="identifier">factor</span><span class="special">(</span><span class="identifier">_factor</span><span class="special">)</span> <span class="special">{}</span>
540
541 <span class="keyword">inline</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">int</span> <span class="identifier">num</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Body uses C++ statement syntax.</span>
542 <span class="identifier">sum</span> <span class="special">+=</span> <span class="identifier">factor</span> <span class="special">*</span> <span class="identifier">num</span><span class="special">;</span>
543 <span class="special">}</span>
544
545 <span class="keyword">private</span><span class="special">:</span> <span class="comment">// Unfortunately, cannot bind so repeat variable types.</span>
546 <span class="keyword">int</span><span class="special">&amp;</span> <span class="identifier">sum</span><span class="special">;</span> <span class="comment">// Access `sum` by reference.</span>
547 <span class="keyword">const</span> <span class="keyword">int</span> <span class="identifier">factor</span><span class="special">;</span> <span class="comment">// Make `factor` constant.</span>
548 <span class="special">}</span> <span class="identifier">add</span><span class="special">(</span><span class="identifier">sum</span><span class="special">,</span> <span class="identifier">factor</span><span class="special">);</span>
549
550 <span class="identifier">add</span><span class="special">(</span><span class="number">1</span><span class="special">);</span>
551 <span class="keyword">int</span> <span class="identifier">nums</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span><span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">};</span>
552 <span class="comment">// Unfortunately, cannot pass as template parameter to `std::for_each`.</span>
553 <span class="keyword">for</span><span class="special">(</span><span class="identifier">size_t</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="number">2</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> <span class="identifier">add</span><span class="special">(</span><span class="identifier">nums</span><span class="special">[</span><span class="identifier">i</span><span class="special">]);</span>
554
555 <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">sum</span> <span class="special">==</span> <span class="number">60</span><span class="special">);</span>
556 <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">report_errors</span><span class="special">();</span>
557 <span class="special">}</span>
558 </pre>
559 <p>
560 </p>
561 </td>
562 <td>
563 <p>
564 </p>
565 <pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Some local scope.</span>
566 <span class="keyword">int</span> <span class="identifier">sum</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">factor</span> <span class="special">=</span> <span class="number">10</span><span class="special">;</span> <span class="comment">// Variables in scope to bind.</span>
567
568 <span class="keyword">void</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">bind</span> <span class="identifier">factor</span><span class="special">,</span> <span class="identifier">bind</span><span class="special">&amp;</span> <span class="identifier">sum</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">num</span><span class="special">)</span> <span class="special">{</span>
569 <span class="identifier">sum</span> <span class="special">+=</span> <span class="identifier">factor</span> <span class="special">*</span> <span class="identifier">num</span><span class="special">;</span>
570 <span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">add</span><span class="special">)</span>
571
572 <span class="identifier">add</span><span class="special">(</span><span class="number">1</span><span class="special">);</span> <span class="comment">// Call the local function.</span>
573 <span class="keyword">int</span> <span class="identifier">nums</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span><span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">};</span>
574 <span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span><span class="identifier">nums</span><span class="special">,</span> <span class="identifier">nums</span> <span class="special">+</span> <span class="number">2</span><span class="special">,</span> <span class="identifier">add</span><span class="special">);</span> <span class="comment">// Pass it to an algorithm.</span>
575
576 <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">sum</span> <span class="special">==</span> <span class="number">60</span><span class="special">);</span> <span class="comment">// Assert final summation value.</span>
577 <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">report_errors</span><span class="special">();</span>
578 <span class="special">}</span>
579 </pre>
580 <p>
581 </p>
582 </td>
583 </tr></tbody>
584 </table></div>
585 <p>
586 <span class="bold"><strong>Global Functor</strong></span>
587 </p>
588 <p>
589 The following example compares local functions with C++ global functors (see
590 also <a href="../../../example/add_global_functor.cpp" target="_top"><code class="literal">add_global_functor.cpp</code></a>
591 and <a href="../../../test/add.cpp" target="_top"><code class="literal">add.cpp</code></a>):
592 </p>
593 <div class="informaltable"><table class="table">
594 <colgroup>
595 <col>
596 <col>
597 </colgroup>
598 <thead><tr>
599 <th>
600 <p>
601 Global Functor
602 </p>
603 </th>
604 <th>
605 <p>
606 Boost.LocalFunction
607 </p>
608 </th>
609 </tr></thead>
610 <tbody><tr>
611 <td>
612 <p>
613 </p>
614 <pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="comment">// Unfortunately, cannot be defined locally (so not a real alternative).</span>
615 <span class="keyword">struct</span> <span class="identifier">global_add</span> <span class="special">{</span> <span class="comment">// Unfortunately, boilerplate code to program the class.</span>
616 <span class="identifier">global_add</span><span class="special">(</span><span class="keyword">int</span><span class="special">&amp;</span> <span class="identifier">_sum</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">_factor</span><span class="special">):</span> <span class="identifier">sum</span><span class="special">(</span><span class="identifier">_sum</span><span class="special">),</span> <span class="identifier">factor</span><span class="special">(</span><span class="identifier">_factor</span><span class="special">)</span> <span class="special">{}</span>
617
618 <span class="keyword">inline</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">int</span> <span class="identifier">num</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Body uses C++ statement syntax.</span>
619 <span class="identifier">sum</span> <span class="special">+=</span> <span class="identifier">factor</span> <span class="special">*</span> <span class="identifier">num</span><span class="special">;</span>
620 <span class="special">}</span>
621
622 <span class="keyword">private</span><span class="special">:</span> <span class="comment">// Unfortunately, cannot bind so repeat variable types.</span>
623 <span class="keyword">int</span><span class="special">&amp;</span> <span class="identifier">sum</span><span class="special">;</span> <span class="comment">// Access `sum` by reference.</span>
624 <span class="keyword">const</span> <span class="keyword">int</span> <span class="identifier">factor</span><span class="special">;</span> <span class="comment">// Make `factor` constant.</span>
625 <span class="special">};</span>
626
627 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span>
628 <span class="keyword">int</span> <span class="identifier">sum</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">factor</span> <span class="special">=</span> <span class="number">10</span><span class="special">;</span>
629
630 <span class="identifier">global_add</span> <span class="identifier">add</span><span class="special">(</span><span class="identifier">sum</span><span class="special">,</span> <span class="identifier">factor</span><span class="special">);</span>
631
632 <span class="identifier">add</span><span class="special">(</span><span class="number">1</span><span class="special">);</span>
633 <span class="keyword">int</span> <span class="identifier">nums</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span><span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">};</span>
634 <span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span><span class="identifier">nums</span><span class="special">,</span> <span class="identifier">nums</span> <span class="special">+</span> <span class="number">2</span><span class="special">,</span> <span class="identifier">add</span><span class="special">);</span> <span class="comment">// Passed as template parameter.</span>
635
636 <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">sum</span> <span class="special">==</span> <span class="number">60</span><span class="special">);</span>
637 <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">report_errors</span><span class="special">();</span>
638 <span class="special">}</span>
639 </pre>
640 <p>
641 </p>
642 </td>
643 <td>
644 <p>
645 </p>
646 <pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Some local scope.</span>
647 <span class="keyword">int</span> <span class="identifier">sum</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">factor</span> <span class="special">=</span> <span class="number">10</span><span class="special">;</span> <span class="comment">// Variables in scope to bind.</span>
648
649 <span class="keyword">void</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">bind</span> <span class="identifier">factor</span><span class="special">,</span> <span class="identifier">bind</span><span class="special">&amp;</span> <span class="identifier">sum</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">num</span><span class="special">)</span> <span class="special">{</span>
650 <span class="identifier">sum</span> <span class="special">+=</span> <span class="identifier">factor</span> <span class="special">*</span> <span class="identifier">num</span><span class="special">;</span>
651 <span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">add</span><span class="special">)</span>
652
653 <span class="identifier">add</span><span class="special">(</span><span class="number">1</span><span class="special">);</span> <span class="comment">// Call the local function.</span>
654 <span class="keyword">int</span> <span class="identifier">nums</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span><span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">};</span>
655 <span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span><span class="identifier">nums</span><span class="special">,</span> <span class="identifier">nums</span> <span class="special">+</span> <span class="number">2</span><span class="special">,</span> <span class="identifier">add</span><span class="special">);</span> <span class="comment">// Pass it to an algorithm.</span>
656
657 <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">sum</span> <span class="special">==</span> <span class="number">60</span><span class="special">);</span> <span class="comment">// Assert final summation value.</span>
658 <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">report_errors</span><span class="special">();</span>
659 <span class="special">}</span>
660 </pre>
661 <p>
662 </p>
663 </td>
664 </tr></tbody>
665 </table></div>
666 <p>
667 However, note that global functors do not allow to define the function locally
668 so they are not a real alternative implementation of local functions.
669 </p>
670 <p>
671 <span class="bold"><strong>Boost.Phoenix</strong></span>
672 </p>
673 <p>
674 The following example compares local functions with <a href="http://www.boost.org/libs/phoenix" target="_top">Boost.Phoenix</a>
675 (see also <a href="../../../example/add_phoenix.cpp" target="_top"><code class="literal">add_phoenix.cpp</code></a>
676 and <a href="../../../test/add.cpp" target="_top"><code class="literal">add.cpp</code></a>):
677 </p>
678 <div class="informaltable"><table class="table">
679 <colgroup>
680 <col>
681 <col>
682 </colgroup>
683 <thead><tr>
684 <th>
685 <p>
686 Boost.Phoenix
687 </p>
688 </th>
689 <th>
690 <p>
691 Boost.LocalFunction
692 </p>
693 </th>
694 </tr></thead>
695 <tbody><tr>
696 <td>
697 <p>
698 </p>
699 <pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span>
700 <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">let</span><span class="special">;</span>
701 <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">local_names</span><span class="special">::</span><span class="identifier">_f</span><span class="special">;</span>
702 <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">cref</span><span class="special">;</span>
703 <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">ref</span><span class="special">;</span>
704 <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">arg_names</span><span class="special">::</span><span class="identifier">_1</span><span class="special">;</span>
705
706 <span class="keyword">int</span> <span class="identifier">sum</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">factor</span> <span class="special">=</span> <span class="number">10</span><span class="special">;</span>
707 <span class="keyword">int</span> <span class="identifier">nums</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">};</span>
708
709 <span class="comment">// Passed to template, `factor` by constant, and defined in expression.</span>
710 <span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span><span class="identifier">nums</span><span class="special">,</span> <span class="identifier">nums</span> <span class="special">+</span> <span class="number">3</span><span class="special">,</span> <span class="identifier">let</span><span class="special">(</span><span class="identifier">_f</span> <span class="special">=</span> <span class="identifier">cref</span><span class="special">(</span><span class="identifier">factor</span><span class="special">))[</span>
711 <span class="comment">// Unfortunately, body cannot use C++ statement syntax.</span>
712 <span class="identifier">ref</span><span class="special">(</span><span class="identifier">sum</span><span class="special">)</span> <span class="special">+=</span> <span class="identifier">_f</span> <span class="special">*</span> <span class="identifier">_1</span><span class="special">,</span> <span class="identifier">_1</span> <span class="comment">// Access `sum` by reference.</span>
713 <span class="special">]);</span>
714
715 <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">sum</span> <span class="special">==</span> <span class="number">60</span><span class="special">);</span>
716 <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">report_errors</span><span class="special">();</span>
717 <span class="special">}</span>
718 </pre>
719 <p>
720 </p>
721 </td>
722 <td>
723 <p>
724 </p>
725 <pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Some local scope.</span>
726 <span class="keyword">int</span> <span class="identifier">sum</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">factor</span> <span class="special">=</span> <span class="number">10</span><span class="special">;</span> <span class="comment">// Variables in scope to bind.</span>
727
728 <span class="keyword">void</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">bind</span> <span class="identifier">factor</span><span class="special">,</span> <span class="identifier">bind</span><span class="special">&amp;</span> <span class="identifier">sum</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">num</span><span class="special">)</span> <span class="special">{</span>
729 <span class="identifier">sum</span> <span class="special">+=</span> <span class="identifier">factor</span> <span class="special">*</span> <span class="identifier">num</span><span class="special">;</span>
730 <span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">add</span><span class="special">)</span>
731
732 <span class="identifier">add</span><span class="special">(</span><span class="number">1</span><span class="special">);</span> <span class="comment">// Call the local function.</span>
733 <span class="keyword">int</span> <span class="identifier">nums</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span><span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">};</span>
734 <span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span><span class="identifier">nums</span><span class="special">,</span> <span class="identifier">nums</span> <span class="special">+</span> <span class="number">2</span><span class="special">,</span> <span class="identifier">add</span><span class="special">);</span> <span class="comment">// Pass it to an algorithm.</span>
735
736 <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">sum</span> <span class="special">==</span> <span class="number">60</span><span class="special">);</span> <span class="comment">// Assert final summation value.</span>
737 <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">report_errors</span><span class="special">();</span>
738 <span class="special">}</span>
739 </pre>
740 <p>
741 </p>
742 </td>
743 </tr></tbody>
744 </table></div>
745 <p>
746 The comparison in this section does not include the <a href="http://www.boost.org/libs/lambda" target="_top">Boost.Lambda</a>
747 library because that library is obsolete and it was replaced by <a href="http://www.boost.org/libs/phoenix" target="_top">Boost.Phoenix</a>.
748 The <a href="http://www.boost.org/libs/phoenix" target="_top">Boost.Phoenix</a> library
749 version 3.0 is used for this comparison.
750 </p>
751 <h4>
752 <a name="boost_localfunction.alternatives.h1"></a>
753 <span class="phrase"><a name="boost_localfunction.alternatives.performances"></a></span><a class="link" href="alternatives.html#boost_localfunction.alternatives.performances">Performances</a>
754 </h4>
755 <p>
756 The following tables compare run-times, compile-times, and binary sizes for
757 the different alternatives to local functions presented in this section.
758 </p>
759 <p>
760 Overall, this library has compile-times and generates binary sizes similar
761 to the ones of the other approaches. This library run-times on <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a>
762 compilers were measured to be larger than other approaches when compiler optimization
763 is enabled (using <code class="computeroutput"><span class="identifier">bjam</span> <span class="identifier">release</span>
764 <span class="special">...</span></code>). However, on compilers that allow
765 to pass local types as template parameters (e.g., MSVC 8.0 or GCC 4.5.3 with
766 <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a> features
767 enabled <code class="literal">-std=c++0x</code>, see also <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm" target="_top">[N2657]</a>
768 and <a href="http://www.boost.org/libs/chrono" target="_top">Boost.Config</a>'s <code class="computeroutput"><span class="identifier">BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS</span></code>)
769 this library automatically generates optimized code that runs as fast as the
770 fastest of the other approaches (see the "Boost.LocalFunction" approach
771 below). When this library local function is specified <code class="computeroutput"><span class="keyword">inline</span></code>
772 (see the "Boost.LocalFunction Inline" approach below and the <a class="link" href="advanced_topics.html" title="Advanced Topics">Advanced Topics</a> section)
773 its run-times are always comparable to both the "Local Functor" and
774 "Global Functor" approaches. However, in these cases the local function
775 cannot be portably passed as template parameter (see <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm" target="_top">[N2657]</a>
776 and <a href="http://www.boost.org/libs/chrono" target="_top">Boost.Config</a>'s <code class="computeroutput"><span class="identifier">BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS</span></code>)
777 so <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span></code> is replaced by a for-loop (on MSVC
778 the for-loop, and not the local function in fact the same applies to local
779 functors, was measured to have worst performances than using <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span></code>).
780 Finally, this library run-times are always among the fastest when no compiler
781 optimization is enabled (using <code class="computeroutput"><span class="identifier">bjam</span>
782 <span class="identifier">debug</span> <span class="special">...</span></code>).
783 </p>
784 <div class="note"><table border="0" summary="Note">
785 <tr>
786 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
787 <th align="left">Note</th>
788 </tr>
789 <tr><td align="left" valign="top"><p>
790 The run-time performances of this library local functions are explained because
791 on <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a>
792 compliant compilers (e.g., GCC 4.5.3 without <code class="literal">-std=c++0x</code>)
793 this library needs to use a function pointer in order to portably pass the
794 local function class as a template parameter (see <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm" target="_top">[N2657]</a>
795 and the <a class="link" href="implementation.html" title="Annex: Implementation">Implementation</a>
796 section). For all tested compilers, this function pointer prevents the compiler
797 optimization algorithms from inlining the local function calls. Instead,
798 the functors used by other approaches (e.g., <a href="http://www.boost.org/libs/phoenix" target="_top">Boost.Phoenix</a>)
799 have been observed to allow all tested compilers to inline all the function
800 calls for optimization. This run-time performance cost is not present on
801 compilers that allow to pass local types as template parameters (e.g., MSVC
802 8.0 or GCC 4.5.3 with <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a>
803 features enabled <code class="literal">-std=c++0x</code>, see <a href="http://www.boost.org/libs/chrono" target="_top">Boost.Config</a>'s
804 <code class="computeroutput"><span class="identifier">BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS</span></code>)
805 because this library does not have to use the extra function pointer to implement
806 the local function call (it directly passes the local class type as template
807 parameter).
808 </p></td></tr>
809 </table></div>
810 <p>
811 This run-time performance cost on <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a>
812 compilers might or might not be an issue depending on the performance requirements
813 of specific applications. For example, an application might already be using
814 a number of indirect function calls (function pointers, virtual functions,
815 etc) for which the overhead added by using the one extra function pointer required
816 by the local function call might not be noticeable within the overall program
817 run-time.
818 </p>
819 <p>
820 Finally, note that only a very simple local function body with just a single
821 instruction was used for the anaylsis presented here (see the source files
822 below). The authors have not studied how this library and the other approaches
823 will perform with respect to each other when a more complex set of instructions
824 is programmed for the local function body (e.g., <span class="emphasis"><em>if</em></span> a
825 more complex set of instructions in the local function body were to inhibit
826 some compiler from inlining function objects also other approaches like <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11
827 lambda functions</a> and <a href="http://www.boost.org/libs/phoenix" target="_top">Boost.Phoenix</a>
828 <span class="emphasis"><em>could</em></span> start to show higher run-times even when optimization
829 is enabled).
830 </p>
831 <p>
832 The following commands were executed from the library example directory to
833 measure compile-time, binary size, and run-time respectively:
834 </p>
835 <pre class="programlisting">&gt; touch &lt;FILE_NAME&gt;.cpp # force recompilation
836 &gt; python chrono.py bjam {release|debug} &lt;FILE_NAME&gt; # compile-time
837 &gt; size &lt;FILE_NAME&gt; # binary size
838 &gt; ./&lt;FILE_NAME&gt; # run-time
839 </pre>
840 <p>
841 The local function was called <code class="literal">1e8</code> times to add together
842 all the elements of a vector and the run-time was measured using <a href="http://www.boost.org/libs/chrono" target="_top">Boost.Chrono</a>
843 averaging over <code class="literal">10</code> executions of the vector summation (see
844 the source files below).
845 </p>
846 <div class="informaltable"><table class="table">
847 <colgroup>
848 <col>
849 <col>
850 <col>
851 </colgroup>
852 <thead><tr>
853 <th>
854 <p>
855 Legend
856 </p>
857 </th>
858 <th>
859 <p>
860 Approach
861 </p>
862 </th>
863 <th>
864 <p>
865 Source File
866 </p>
867 </th>
868 </tr></thead>
869 <tbody>
870 <tr>
871 <td>
872 <p>
873 <span class="inlinemediaobject"><img src="../../../example/profile_legend_local_function.png" alt="profile_legend_local_function"></span>
874 </p>
875 </td>
876 <td>
877 <p>
878 <a href="http://www.boost.org/libs/local_function" target="_top">Boost.LocalFunction</a>
879 </p>
880 </td>
881 <td>
882 <p>
883 <a href="../../../example/profile_local_function.cpp" target="_top"><code class="literal">profile_local_function.cpp</code></a>
884 </p>
885 </td>
886 </tr>
887 <tr>
888 <td>
889 <p>
890 <span class="inlinemediaobject"><img src="../../../example/profile_legend_local_function_inline.png" alt="profile_legend_local_function_inline"></span>
891 </p>
892 </td>
893 <td>
894 <p>
895 <a href="http://www.boost.org/libs/local_function" target="_top">Boost.LocalFunction</a>
896 inline
897 </p>
898 </td>
899 <td>
900 <p>
901 <a href="../../../example/profile_local_function_inline.cpp" target="_top"><code class="literal">profile_local_function_inline.cpp</code></a>
902 </p>
903 </td>
904 </tr>
905 <tr>
906 <td>
907 <p>
908 <span class="inlinemediaobject"><img src="../../../example/profile_legend_cxx11_lambda.png" alt="profile_legend_cxx11_lambda"></span>
909 </p>
910 </td>
911 <td>
912 <p>
913 <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a>
914 Lambda Function <a href="#ftn.boost_localfunction.alternatives.f0" class="footnote" name="boost_localfunction.alternatives.f0"><sup class="footnote">[a]</sup></a>
915 </p>
916 </td>
917 <td>
918 <p>
919 <a href="../../../example/profile_cxx11_lambda.cpp" target="_top"><code class="literal">profile_cxx11_lambda.cpp</code></a>
920 </p>
921 </td>
922 </tr>
923 <tr>
924 <td>
925 <p>
926 <span class="inlinemediaobject"><img src="../../../example/profile_legend_local_functor.png" alt="profile_legend_local_functor"></span>
927 </p>
928 </td>
929 <td>
930 <p>
931 Local Functor
932 </p>
933 </td>
934 <td>
935 <p>
936 <a href="../../../example/profile_local_functor.cpp" target="_top"><code class="literal">profile_local_functor.cpp</code></a>
937 </p>
938 </td>
939 </tr>
940 <tr>
941 <td>
942 <p>
943 <span class="inlinemediaobject"><img src="../../../example/profile_legend_global_functor.png" alt="profile_legend_global_functor"></span>
944 </p>
945 </td>
946 <td>
947 <p>
948 Global Functor
949 </p>
950 </td>
951 <td>
952 <p>
953 <a href="../../../example/profile_global_functor.cpp" target="_top"><code class="literal">profile_global_functor.cpp</code></a>
954 </p>
955 </td>
956 </tr>
957 <tr>
958 <td>
959 <p>
960 <span class="inlinemediaobject"><img src="../../../example/profile_legend_phoenix.png" alt="profile_legend_phoenix"></span>
961 </p>
962 </td>
963 <td>
964 <p>
965 <a href="http://www.boost.org/libs/phoenix" target="_top">Boost.Phoenix</a>
966 </p>
967 </td>
968 <td>
969 <p>
970 <a href="../../../example/profile_phoenix.cpp" target="_top"><code class="literal">profile_phoenix.cpp</code></a>
971 </p>
972 </td>
973 </tr>
974 </tbody>
975 <tbody class="footnotes"><tr><td colspan="3"><div id="ftn.boost_localfunction.alternatives.f0" class="footnote"><p><a href="#boost_localfunction.alternatives.f0" class="para"><sup class="para">[a] </sup></a>
976 Measurements available only for <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a>
977 compilers.
978 </p></div></td></tr></tbody>
979 </table></div>
980 <div class="informaltable"><table class="table">
981 <colgroup><col></colgroup>
982 <thead><tr><th>
983 <p>
984 GCC 4.5.3 With C++11 Lambda Functions and "Local Classes as
985 Template Parameters" (<code class="literal">bjam cxxflags=-std=c++0x ...</code>)
986 </p>
987 </th></tr></thead>
988 <tbody>
989 <tr><td>
990 <p>
991 <span class="bold"><strong>Compiled with <code class="literal">bjam release ...</code>
992 for maximum optimization (<code class="literal">-O3 -finline-functions</code>)</strong></span>
993 <span class="inlinemediaobject"><img src="../../../example/profile_gcc_cxx11_release.png" width="1170" alt="profile_gcc_cxx11_release"></span>
994 </p>
995 </td></tr>
996 <tr><td>
997 <p>
998 <span class="bold"><strong>Compiled with <code class="literal">bjam debug ...</code>
999 for no optimization (<code class="literal">-O0 -fno-inline</code>)</strong></span>
1000 <span class="inlinemediaobject"><img src="../../../example/profile_gcc_cxx11_debug.png" width="1170" alt="profile_gcc_cxx11_debug"></span>
1001 </p>
1002 </td></tr>
1003 </tbody>
1004 </table></div>
1005 <div class="informaltable"><table class="table">
1006 <colgroup><col></colgroup>
1007 <thead><tr><th>
1008 <p>
1009 MSVC 8.0 With "Local Classes as Template Parameters" (Without
1010 C++11 Lambda Functions)
1011 </p>
1012 </th></tr></thead>
1013 <tbody>
1014 <tr><td>
1015 <p>
1016 <span class="bold"><strong>Compiled with <code class="literal">bjam release ...</code>
1017 for maximum optimization (<code class="literal">/O2 /Ob2</code>)</strong></span>
1018 <span class="inlinemediaobject"><img src="../../../example/profile_msvc_release.png" width="1170" alt="profile_msvc_release"></span>
1019 </p>
1020 </td></tr>
1021 <tr><td>
1022 <p>
1023 <span class="bold"><strong>Compiled with <code class="literal">bjam debug ...</code>
1024 for no optimization (<code class="literal">/Od /Ob0</code>)</strong></span> <span class="inlinemediaobject"><img src="../../../example/profile_msvc_debug.png" width="1170" alt="profile_msvc_debug"></span>
1025 </p>
1026 </td></tr>
1027 </tbody>
1028 </table></div>
1029 <div class="informaltable"><table class="table">
1030 <colgroup><col></colgroup>
1031 <thead><tr><th>
1032 <p>
1033 GCC 4.3.4 With <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a>
1034 Only (Without <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a>
1035 Lambda Functions and Without "Local Classes as Template Parameters")
1036 </p>
1037 </th></tr></thead>
1038 <tbody>
1039 <tr><td>
1040 <p>
1041 <span class="bold"><strong>Compiled with <code class="literal">bjam release ...</code>
1042 for maximum optimization (<code class="literal">-O3 -finline-functions</code>)</strong></span>
1043 <span class="inlinemediaobject"><img src="../../../example/profile_gcc_release.png" width="1170" alt="profile_gcc_release"></span>
1044 </p>
1045 </td></tr>
1046 <tr><td>
1047 <p>
1048 <span class="bold"><strong>Compiled with <code class="literal">bjam debug ...</code>
1049 for no optimization (<code class="literal">-O0 -fno-inline</code>)</strong></span>
1050 <span class="inlinemediaobject"><img src="../../../example/profile_gcc_debug.png" width="1170" alt="profile_gcc_debug"></span>
1051 </p>
1052 </td></tr>
1053 </tbody>
1054 </table></div>
1055 </div>
1056 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
1057 <td align="left"></td>
1058 <td align="right"><div class="copyright-footer">Copyright &#169; 2009-2012 Lorenzo
1059 Caminiti<p>
1060 Distributed under the Boost Software License, Version 1.0 (see accompanying
1061 file LICENSE_1_0.txt or a copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
1062 </p>
1063 </div></td>
1064 </tr></table>
1065 <hr>
1066 <div class="spirit-nav">
1067 <a accesskey="p" href="examples.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="no_variadic_macros.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
1068 </div>
1069 </body>
1070 </html>