Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r71090 - in sandbox/local: boost/local/aux_/function_macros libs/local/doc/qbk libs/local/example
From: lorcaminiti_at_[hidden]
Date: 2011-04-07 16:41:03


Author: lcaminiti
Date: 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
New Revision: 71090
URL: http://svn.boost.org/trac/boost/changeset/71090

Log:
Starting changes to improve performances on C++03 enabled compilers.
Added:
   sandbox/local/libs/local/example/benchmark_boost_phoenix.00.cpp (contents, props changed)
   sandbox/local/libs/local/example/bmc_local.cpp (contents, props changed)
   sandbox/local/libs/local/example/bmc_phoenix.cpp (contents, props changed)
   sandbox/local/libs/local/example/cg00.cpp (contents, props changed)
   sandbox/local/libs/local/example/cl00.cpp (contents, props changed)
   sandbox/local/libs/local/example/gred_add01.cpp (contents, props changed)
   sandbox/local/libs/local/example/l00.cpp (contents, props changed)
   sandbox/local/libs/local/example/l01.cpp (contents, props changed)
   sandbox/local/libs/local/example/l02.cpp (contents, props changed)
   sandbox/local/libs/local/example/l03.cpp (contents, props changed)
   sandbox/local/libs/local/example/l04.cpp (contents, props changed)
   sandbox/local/libs/local/example/l05.cpp (contents, props changed)
   sandbox/local/libs/local/example/l06.cpp (contents, props changed)
   sandbox/local/libs/local/example/l07.cpp (contents, props changed)
   sandbox/local/libs/local/example/l08.cpp (contents, props changed)
   sandbox/local/libs/local/example/l09.cpp (contents, props changed)
   sandbox/local/libs/local/example/l10.cpp (contents, props changed)
   sandbox/local/libs/local/example/p00.cpp (contents, props changed)
   sandbox/local/libs/local/example/tom_add_boost_local.cpp (contents, props changed)
   sandbox/local/libs/local/example/tom_add_boost_phoenix.cpp (contents, props changed)
   sandbox/local/libs/local/example/tom_local.cpp (contents, props changed)
   sandbox/local/libs/local/example/tom_phoenix.cpp (contents, props changed)
   sandbox/local/libs/local/example/tparam_trick.00.cpp (contents, props changed)
   sandbox/local/libs/local/example/tparam_trick.01.cpp (contents, props changed)
   sandbox/local/libs/local/example/tparam_trick.02.cpp (contents, props changed)
   sandbox/local/libs/local/example/tparam_trick.03.cpp (contents, props changed)
   sandbox/local/libs/local/example/tparam_trick.04.cpp (contents, props changed)
   sandbox/local/libs/local/example/tparam_trick.05.cpp (contents, props changed)
   sandbox/local/libs/local/example/tparam_trick.06.cpp (contents, props changed)
   sandbox/local/libs/local/example/tparam_trick.07.cpp (contents, props changed)
   sandbox/local/libs/local/example/tparam_trick.08.cpp (contents, props changed)
   sandbox/local/libs/local/example/tparam_trick.09.cpp (contents, props changed)
   sandbox/local/libs/local/example/tparam_trick.10.cpp (contents, props changed)
Text files modified:
   sandbox/local/boost/local/aux_/function_macros/name.hpp | 52 +++++++++++++++++++++++++++++++--------
   sandbox/local/libs/local/doc/qbk/release_notes.qbk | 7 +++++
   sandbox/local/libs/local/example/benchmark_boost_lambda.cpp | 12 +++++---
   sandbox/local/libs/local/example/benchmark_boost_local.cpp | 12 ++++++---
   sandbox/local/libs/local/example/benchmark_boost_phoenix.cpp | 15 +++++------
   sandbox/local/libs/local/example/benchmark_global_functor.cpp | 13 ++++++---
   sandbox/local/libs/local/example/benchmark_local_functor.cpp | 19 +++++++------
   7 files changed, 88 insertions(+), 42 deletions(-)

Modified: sandbox/local/boost/local/aux_/function_macros/name.hpp
==============================================================================
--- sandbox/local/boost/local/aux_/function_macros/name.hpp (original)
+++ sandbox/local/boost/local/aux_/function_macros/name.hpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -10,18 +10,26 @@
 #include "../symbol.hpp"
 // For BOOST_TYPEOF.
 #include "../scope_exit/scope_exit.hpp" // Use this lib's ScopeExit impl.
+#include <boost/preprocessor/control/iif.hpp>
 
 // PRIVATE //
 
-#define BOOST_LOCAL_AUX_FUNCTION_NAME_(local_function_name, id) \
+#define BOOST_LOCAL_AUX_FUNCTION_NAME_END_LOCAL_FUNCTOR_( \
+ local_functor_name, local_function_name, \
+ is_local_function_member_public, id) \
     /* `PARAMS() { ... }` expandsion here -- still within functor class */ \
     /* class functor ## __LINE__ { ... */ \
- public: \
+ BOOST_PP_IIF(is_local_function_member_public, \
         /* member var with function name for recursive calls; must be */ \
         /* `public` because is it also used by this macro but outside */ \
         /* the functor class to deduce the functor type; it cannot be */ \
         /* `const` because it is init after construction (because */ \
         /* constructor doesn't know local function name) */ \
+ public: \
+ , \
+ /* if optimized, then no need to access this for typeof */ \
+ private: \
+ ) \
         BOOST_LOCAL_AUX_SYMBOL_FUNCTOR_TYPE local_function_name; \
     private: \
         /* called by the constructor to init member variable for recursion */ \
@@ -31,22 +39,44 @@
     /* declares object for local class functor (but this functor cannot be */ \
     /* passed as template parameter); cannot be `const` `abstract_function` */ \
     /* is not passed as const to `function` to make the function call */ \
- } BOOST_LOCAL_AUX_SYMBOL_FUNCTOR_OBJECT_NAME(local_function_name)( \
- BOOST_LOCAL_AUX_SYMBOL_ARGS_VARIABLE_NAME.value); \
+ } local_functor_name(BOOST_LOCAL_AUX_SYMBOL_ARGS_VARIABLE_NAME.value);
+
+#define BOOST_LOCAL_AUX_FUNCTION_NAME_DECL_GLOBAL_FUNCTOR_( \
+ local_functor_name, local_function_name, id) \
     /* declares actual functor for the local function (of type */ \
     /* local::function which can be passed as template parameter); this */ \
     /* is correctly `const` because it is directly visible to programmers */ \
     /* which cannot re-assign the local functor (they can only call it) */ \
- BOOST_TYPEOF(BOOST_LOCAL_AUX_SYMBOL_FUNCTOR_OBJECT_NAME( \
- local_function_name).local_function_name) const \
- local_function_name(BOOST_LOCAL_AUX_SYMBOL_FUNCTOR_OBJECT_NAME( \
- local_function_name));
+ BOOST_TYPEOF(local_functor_name.local_function_name) const \
+ local_function_name(local_functor_name);
 
 // PUBLIC //
 
-#define BOOST_LOCAL_AUX_FUNCTION_NAME(local_function_name) \
- BOOST_LOCAL_AUX_FUNCTION_NAME_(local_function_name, __LINE__) \
+// Limitation: This is faster (smaller run-time than `FUNCION_NAME`) but it
+// cannot be passed as template parameter on ISO C++.
+#define BOOST_LOCAL_AUX_FUNCTION_NAME_OPTIMIZED(local_function_name) \
+ BOOST_LOCAL_AUX_FUNCTION_NAME_END_LOCAL_FUNCTOR_(local_function_name, \
+ local_function_name, 0 /* local func mem not public */, __LINE__)
+
+// ISO C++ does not allow to pass local classes as template parameters. But
+// if can use no ISO C++ standard features and MSVC compiler (which allows to
+// pass local classes as template parameters), than pass local class as
+// template parameter without the extra global functor to reduce run-time.
+#if !defined(BOOST_LOCAL_CONFIG_COMPLIANT) && defined(_MSC_VER)
+ #define BOOST_LOCAL_AUX_FUNCTION_NAME(local_function_name) \
+ BOOST_LOCAL_AUX_FUNCTION_NAME_OPTIMIZED(local_function_name)
+#else
+ #define BOOST_LOCAL_AUX_FUNCTION_NAME(local_function_name) \
+ BOOST_LOCAL_AUX_FUNCTION_NAME_END_LOCAL_FUNCTOR_( \
+ BOOST_LOCAL_AUX_SYMBOL_FUNCTOR_OBJECT_NAME( \
+ local_function_name), \
+ local_function_name, 1 /* local func mem public */, __LINE__) \
+ /* use the global functor increases run-time (because its uses one */ \
+ /* indirected function call that cannot be optimized awa) */ \
+ BOOST_LOCAL_AUX_FUNCTION_NAME_DECL_GLOBAL_FUNCTOR_( \
+ BOOST_LOCAL_AUX_SYMBOL_FUNCTOR_OBJECT_NAME( \
+ local_function_name), local_function_name, __LINE__)
+#endif
 
 #endif // #include guard
 
-

Modified: sandbox/local/libs/local/doc/qbk/release_notes.qbk
==============================================================================
--- sandbox/local/libs/local/doc/qbk/release_notes.qbk (original)
+++ sandbox/local/libs/local/doc/qbk/release_notes.qbk 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -42,6 +42,13 @@
 
 * Shall `this_` be named `_this` instead? Ask Boosters if there is some guideline for consistency. Maybe Boost uses `..._` is for statements (like `if_`) and `_...` for variables (like `_1`)... if that is the case then I should use `_this`.
 
+* Rename `abstract_function` to `function_interface`.
+
+* Provide a special macro `BOOST_LOCAL_FUNCTION_NAME_OPTIMIZED` that runs faster (by using the local functor directly without using the global `boost::local::function` functor instead).
+Make both local blocks and exits use this optimized local function variant.
+Document that this optimized local function variant cannot be passed as template parameter unless it is first manually reassigned to the global `boost::local::function` functor or C++03 feature is supported by the compiler.
+On C++03, make `BOOST_LOCAL_FUNCTION_NAME` be the same as `BOOST_LOCAL_FUNCTION_NAME_OPTIMIZED`.
+
 [endsect]
 
 [endsect]

Modified: sandbox/local/libs/local/example/benchmark_boost_lambda.cpp
==============================================================================
--- sandbox/local/libs/local/example/benchmark_boost_lambda.cpp (original)
+++ sandbox/local/libs/local/example/benchmark_boost_lambda.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -3,18 +3,19 @@
 #include <iostream>
 #include <vector>
 #include <algorithm>
+#include <cassert>
 
-#define N 10000
+#define N 1e4
+#define S N * 1e2
 
 int main() {
     using boost::lambda::_1;
- using boost::lambda::var;
 
     double sum = 0.0;
- int factor = 10;
+ int factor = 1;
 
- std::vector<double> v(N * 100);
- std::fill(v.begin(), v.end(), 10);
+ std::vector<double> v(S);
+ std::fill(v.begin(), v.end(), 1.0);
 
     for (size_t n = 0; n < N; ++n) {
         std::for_each(v.begin(), v.end(), (
@@ -23,6 +24,7 @@
     }
 
     std::cout << sum << std::endl;
+ assert(sum == N * S);
     return 0;
 }
 

Modified: sandbox/local/libs/local/example/benchmark_boost_local.cpp
==============================================================================
--- sandbox/local/libs/local/example/benchmark_boost_local.cpp (original)
+++ sandbox/local/libs/local/example/benchmark_boost_local.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -3,25 +3,29 @@
 #include <vector>
 #include <algorithm>
 #include <iostream>
+#include <cassert>
 
-#define N 10000
+#define N 1e4
+#define S N * 1e2
 
 int main() {
     double sum = 0.0;
- int factor = 10;
+ int factor = 1;
+
+ std::vector<double> v(S);
+ std::fill(v.begin(), v.end(), 1.0);
 
     void BOOST_LOCAL_FUNCTION_PARAMS( (const double& num)
             (bind& sum) (const bind& factor) ) {
         sum += factor * num;
     } BOOST_LOCAL_FUNCTION_NAME(add)
 
- std::vector<double> v(N * 100);
- std::fill(v.begin(), v.end(), 10);
     for (size_t n = 0; n < N; ++n) {
         std::for_each(v.begin(), v.end(), add);
     }
 
     std::cout << sum << std::endl;
+ assert(sum == N * S);
     return 0;
 }
 

Added: sandbox/local/libs/local/example/benchmark_boost_phoenix.00.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/benchmark_boost_phoenix.00.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,38 @@
+
+#include <boost/spirit/include/phoenix.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+#define N 10000
+
+int f() { return -1; }
+
+int main() {
+ using boost::phoenix::let;
+ using boost::phoenix::local_names::_f;
+ using boost::phoenix::cref;
+ using boost::phoenix::ref;
+ using boost::phoenix::arg_names::_1;
+ using boost::phoenix::val;
+
+ double sum = 0.0;
+ int factor = 10;
+
+ struct l {
+ double f(const double& x) { return x; }
+ } ll;
+
+ std::vector<double> v(N * 100);
+ std::fill(v.begin(), v.end(), 10);
+
+ for (size_t n = 0; n < N; ++n) {
+ std::for_each(v.begin(), v.end(), (
+ ref(sum) += factor * ll.f(1.0 * _1)
+ ));
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Modified: sandbox/local/libs/local/example/benchmark_boost_phoenix.cpp
==============================================================================
--- sandbox/local/libs/local/example/benchmark_boost_phoenix.cpp (original)
+++ sandbox/local/libs/local/example/benchmark_boost_phoenix.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -3,22 +3,20 @@
 #include <iostream>
 #include <vector>
 #include <algorithm>
+#include <cassert>
 
-#define N 10000
+#define N 1e4
+#define S N * 1e2
 
 int main() {
- using boost::phoenix::let;
- using boost::phoenix::local_names::_f;
- using boost::phoenix::cref;
     using boost::phoenix::ref;
     using boost::phoenix::arg_names::_1;
- using boost::phoenix::val;
 
     double sum = 0.0;
- int factor = 10;
+ int factor = 1;
 
- std::vector<double> v(N * 100);
- std::fill(v.begin(), v.end(), 10);
+ std::vector<double> v(S);
+ std::fill(v.begin(), v.end(), 1.0);
 
     for (size_t n = 0; n < N; ++n) {
         std::for_each(v.begin(), v.end(), (
@@ -27,6 +25,7 @@
     }
 
     std::cout << sum << std::endl;
+ assert(sum == N * S);
     return 0;
 }
 

Modified: sandbox/local/libs/local/example/benchmark_global_functor.cpp
==============================================================================
--- sandbox/local/libs/local/example/benchmark_global_functor.cpp (original)
+++ sandbox/local/libs/local/example/benchmark_global_functor.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -2,12 +2,14 @@
 #include <iostream>
 #include <vector>
 #include <algorithm>
+#include <cassert>
 
-#define N 10000
+#define N 1e4
+#define S N * 1e2
 
 struct global_add {
     global_add(double& _sum, int _factor): sum(_sum), factor(_factor) {}
- void operator()(double num) {
+ void operator()(const double& num) {
         sum += factor * num;
     }
 private:
@@ -17,10 +19,10 @@
 
 int main() {
     double sum = 0.0;
- int factor = 10;
+ int factor = 1;
 
- std::vector<double> v(N * 100);
- std::fill(v.begin(), v.end(), 10);
+ std::vector<double> v(S);
+ std::fill(v.begin(), v.end(), 1.0);
 
     global_add add(sum, factor);
 
@@ -29,6 +31,7 @@
     }
 
     std::cout << sum << std::endl;
+ assert(sum == N * S);
     return 0;
 }
 

Modified: sandbox/local/libs/local/example/benchmark_local_functor.cpp
==============================================================================
--- sandbox/local/libs/local/example/benchmark_local_functor.cpp (original)
+++ sandbox/local/libs/local/example/benchmark_local_functor.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -2,16 +2,21 @@
 #include <iostream>
 #include <vector>
 #include <algorithm>
+#include <cassert>
 
-#define N 10000
+#define N 1e4
+#define S N * 1e2
 
 int main() {
     double sum = 0.0;
- int factor = 10;
+ int factor = 1;
+
+ std::vector<double> v(S);
+ std::fill(v.begin(), v.end(), 1.0);
 
     struct local_add {
         local_add(double& _sum, int _factor): sum(_sum), factor(_factor) {}
- void operator()(double num) {
+ void operator()(const double& num) {
             sum += factor * num;
         }
     private:
@@ -20,16 +25,12 @@
     };
     local_add add(sum, factor);
 
- std::vector<double> v(N * 100);
- std::fill(v.begin(), v.end(), 10);
-
     for (size_t n = 0; n < N; ++n) {
- for (size_t i = 0; i < v.size(); ++i) {
- add(v[i]);
- }
+ for (size_t i = 0; i < v.size(); ++i) add(v[i]); // Can't use for_each.
     }
 
     std::cout << sum << std::endl;
+ assert(sum == N * S);
     return 0;
 }
 

Added: sandbox/local/libs/local/example/bmc_local.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/bmc_local.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,33 @@
+
+#include <boost/local/function.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+#define N 30000
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ std::vector<double> v(N);
+ std::fill(v.begin(), v.end(), 10);
+
+ void BOOST_LOCAL_FUNCTION_PARAMS( (double num)
+ (bind& sum) (const bind factor)
+ ) {
+ sum += factor * num;
+ } BOOST_LOCAL_FUNCTION_NAME(add)
+
+ for (size_t n = 0; n < N; ++n) {
+ std::for_each(v.begin(), v.end(), add);
+// for (size_t i = 0; i < v.size(); ++i) {
+// sum += factor * v[i];//10;
+// add(v[i]);
+// }
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/bmc_phoenix.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/bmc_phoenix.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,29 @@
+
+#include <boost/spirit/include/phoenix.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+int main() {
+ using boost::phoenix::let;
+ using boost::phoenix::local_names::_f;
+ using boost::phoenix::cref;
+ using boost::phoenix::ref;
+ using boost::phoenix::arg_names::_1;
+ using boost::phoenix::val;
+
+ double sum = 0.0;
+ int factor = 10;
+
+ std::vector<double> v(1000000);
+ std::fill(v.begin(), v.end(), 10);
+ for (size_t n = 0; n < 10000; ++n) {
+ std::for_each(v.begin(), v.end(), (
+ ref(sum) += factor * _1
+ ));
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/cg00.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/cg00.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,38 @@
+
+// Copyright (C) 2009-2011 Lorenzo Caminiti
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0 (see accompanying file LICENSE_1_0.txt or a
+// copy at http://www.boost.org/LICENSE_1_0.txt).
+
+#include <boost/local/function.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+ struct global_add {
+ global_add(double& _sum, int _factor): sum(_sum), factor(_factor) {}
+ void operator()(double num) {
+ sum += factor * num;
+ }
+ private:
+ double& sum;
+ const int factor;
+ };
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ std::vector<double> v(1000000);
+ std::fill(v.begin(), v.end(), 10);
+
+ global_add add(sum, factor);
+
+ for(int i = 0; i < 10000; ++i) {
+ std::for_each(v.begin(), v.end(), add);
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/cl00.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/cl00.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,39 @@
+
+// Copyright (C) 2009-2011 Lorenzo Caminiti
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0 (see accompanying file LICENSE_1_0.txt or a
+// copy at http://www.boost.org/LICENSE_1_0.txt).
+
+#include <boost/local/function.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ std::vector<double> v(1000000);
+ std::fill(v.begin(), v.end(), 10);
+
+ struct local_add {
+ local_add(double& _sum, int _factor): sum(_sum), factor(_factor) {}
+ void operator()(double num) {
+ sum += factor * num;
+ }
+ private:
+ double& sum;
+ const int factor;
+ };
+ local_add add(sum, factor);
+
+ for (int i = 0; i < 10000; ++i) {
+ for (size_t j = 0; j < v.size(); ++j) {
+ add(v[j]);
+ }
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/gred_add01.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/gred_add01.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,36 @@
+
+// Copyright (C) 2009-2011 Lorenzo Caminiti
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0 (see accompanying file LICENSE_1_0.txt or a
+// copy at http://www.boost.org/LICENSE_1_0.txt).
+
+//[ add_cpp
+#include <boost/local/function.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ std::vector<double> v(1000000);
+
+ std::fill(v.begin(), v.end(), 10);
+
+ void BOOST_LOCAL_FUNCTION_PARAMS( (double& num)
+ (const bind& factor) (bind& sum) ) {
+ sum += factor * num;
+ } BOOST_LOCAL_FUNCTION_NAME(add)
+
+ for(int i = 0; i < 10000; ++i)
+ {
+ std::for_each(v.begin(), v.end(), add);
+ }
+
+ std::cout << sum << std::endl;
+
+ return 0;
+}
+//]
+

Added: sandbox/local/libs/local/example/l00.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/l00.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,31 @@
+
+// Copyright (C) 2009-2011 Lorenzo Caminiti
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0 (see accompanying file LICENSE_1_0.txt or a
+// copy at http://www.boost.org/LICENSE_1_0.txt).
+
+#include <boost/local/function.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ std::vector<double> v(1000000);
+ std::fill(v.begin(), v.end(), 10);
+
+ void BOOST_LOCAL_FUNCTION_PARAMS( (double num)
+ (const bind factor) (bind& sum) ) {
+ sum += factor * num;
+ } BOOST_LOCAL_FUNCTION_NAME(add)
+
+ for(int i = 0; i < 10000; ++i) {
+ std::for_each(v.begin(), v.end(), add);
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/l01.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/l01.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,68 @@
+
+// Copyright (C) 2009-2011 Lorenzo Caminiti
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0 (see accompanying file LICENSE_1_0.txt or a
+// copy at http://www.boost.org/LICENSE_1_0.txt).
+
+#include <boost/local/function.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ std::vector<double> v(1000000);
+ std::fill(v.begin(), v.end(), 10);
+
+void (*ERROR_missing_result_type_before_the_local_function_parameter_macro_id20)(); typedef void (*boost_local_auxXdeduce_result_tag20)( int ERROR_missing_result_type_before_the_local_function_parameter_macro_id20); typedef __typeof__(boost::type_of::ensure_obj(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref( ERROR_missing_result_type_before_the_local_function_parameter_macro_id20, (boost_local_auxXdeduce_result_tag20)0)))) boost_local_auxXdeduce_result_wrap20; typedef boost_local_auxXdeduce_result_wrap20::type boost_local_auxXdeduce_result_capture20; struct boost_local_auxXdeduce_result_params20 { typedef boost_local_auxXdeduce_result_capture20 function_ptr_type; }; typedef boost::remove_pointer< boost_local_auxXdeduce_result_params20::function_ptr_type >::type boost_local_auxXdeduce_result_function_type20; typedef boost::function_traits< boost_local_auxXdeduce_result_function_type20>::result_type boost_local_auxXresult_type20; typedef void (*boost_se_tag_0_20)(int factor ); typedef void (*boos
t_se_tag_1_20)(int & sum ); typedef __typeof__(boost::type_of::ensure_obj(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref(factor, (boost_se_tag_0_20)0)))) boost_se_wrapped_t_0_20; typedef boost_se_wrapped_t_0_20::type boost_se_capture_t_0_20; typedef __typeof__(boost::type_of::ensure_obj(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref(& sum, (boost_se_tag_1_20)0)))) boost_se_wrapped_t_1_20; typedef boost_se_wrapped_t_1_20::type boost_se_capture_t_1_20; struct boost_se_params_t_20 { typedef boost_se_capture_t_0_20 boost_se_param_t_0_20; typedef boost_se_capture_t_1_20 boost_se_param_t_1_20; boost::scope_exit::aux::member< boost_se_param_t_0_20, boost_se_tag_0_20 > boost_se_param_0_20; boost::scope_exit::aux::member< boost_se_param_t_1_20, boost_se_tag_1_20 > boost_se_param_1_20; } boost_local_auxXparams20 = { { boost::scope_exit::aux::deref(factor, (boost_se_tag_0_20)0) } , { boost::scope_exit::aux::deref(& sum, (boost_se_tag_1_20)0) } }; boost::scope_exit::aux::declared< boost::scope_
exit::aux::resolve< sizeof(boost_local_auxXargs) >::cmp1<0>::cmp2 > boost_local_auxXargs; boost_local_auxXargs.value = &boost_local_auxXparams20;
+
+
+ class boost_local_auxXfunctor20
+ //: public ::boost::local::aux::abstract_function< boost_local_auxXresult_type20 ( double num ), 0 >
+ {
+ typedef boost_local_auxXresult_type20 (boost_local_auxXfunction_type) ( double num );
+ public:
+ explicit boost_local_auxXfunctor20( void* binding_data, double& _sum, int _factor)
+ : boost_local_auxXbinds(static_cast< boost_se_params_t_20*>(binding_data)) , sum_(_sum), factor_(_factor)
+ { /*boost_local_auxXinit_recursion();*/ }
+
+ boost_local_auxXresult_type20 operator()( ::boost::function_traits< boost_local_auxXfunction_type>::arg1_type arg1 )
+ { return boost_local_auxXbody(
+ sum_//boost_local_auxXbinds-> boost_se_param_0_20.value
+ , boost_local_auxXbinds-> boost_se_param_1_20.value , arg1 );
+ }
+ private:
+// typedef ::boost::local::function<boost_local_auxXfunction_type, 0 > boost_local_auxXfunctor_type;
+// typedef ::boost::add_const< boost_se_params_t_20:: boost_se_param_t_0_20 >::type factorXboost_local_auxXtypeof_type ;
+// typedef boost_se_params_t_20:: boost_se_param_t_1_20 & sumXboost_local_auxXtypeof_type ;
+ boost_se_params_t_20* boost_local_auxXbinds;
+ double& sum_;
+ const int factor_;
+// boost::scope_exit::aux::undeclared boost_local_auxXargs;
+
+ boost_local_auxXresult_type20 boost_local_auxXbody(
+ ::boost::add_const< boost_se_params_t_20:: boost_se_param_t_0_20 >::type factor
+ , /*boost_se_params_t_20:: boost_se_param_t_1_20*/double & sum , double num ) const {
+ sum += factor * num;
+ }
+// public:
+// boost_local_auxXfunctor_type add;
+// private:
+// void boost_local_auxXinit_recursion() {
+// //add = *this;
+// }
+ } boost_local_auxXfunctorXadd( boost_local_auxXargs.value, sum, factor);
+ // __typeof__(boost::type_of::ensure_obj(boost_local_auxXfunctorXadd.add)) const add(boost_local_auxXfunctorXadd);
+
+ for(int i = 0; i < 10000; ++i) {
+ for(size_t j = 0; j < v.size(); ++j) {
+ boost_local_auxXfunctorXadd(v[j]);
+ }
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/l02.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/l02.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,78 @@
+
+// Copyright (C) 2009-2011 Lorenzo Caminiti
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0 (see accompanying file LICENSE_1_0.txt or a
+// copy at http://www.boost.org/LICENSE_1_0.txt).
+
+#include <boost/local/function.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ std::vector<double> v(1000000);
+ std::fill(v.begin(), v.end(), 10);
+
+void (*ERROR_missing_result_type_before_the_local_function_parameter_macro_id20)(); typedef void (*boost_local_auxXdeduce_result_tag20)( int ERROR_missing_result_type_before_the_local_function_parameter_macro_id20); typedef __typeof__(boost::type_of::ensure_obj(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref( ERROR_missing_result_type_before_the_local_function_parameter_macro_id20, (boost_local_auxXdeduce_result_tag20)0)))) boost_local_auxXdeduce_result_wrap20; typedef boost_local_auxXdeduce_result_wrap20::type boost_local_auxXdeduce_result_capture20; struct boost_local_auxXdeduce_result_params20 { typedef boost_local_auxXdeduce_result_capture20 function_ptr_type; }; typedef boost::remove_pointer< boost_local_auxXdeduce_result_params20::function_ptr_type >::type boost_local_auxXdeduce_result_function_type20; typedef boost::function_traits< boost_local_auxXdeduce_result_function_type20>::result_type boost_local_auxXresult_type20; typedef void (*boost_se_tag_0_20)(int factor ); typedef void (*boos
t_se_tag_1_20)(int & sum ); typedef __typeof__(boost::type_of::ensure_obj(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref(factor, (boost_se_tag_0_20)0)))) boost_se_wrapped_t_0_20; typedef boost_se_wrapped_t_0_20::type boost_se_capture_t_0_20; typedef __typeof__(boost::type_of::ensure_obj(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref(& sum, (boost_se_tag_1_20)0)))) boost_se_wrapped_t_1_20; typedef boost_se_wrapped_t_1_20::type boost_se_capture_t_1_20; struct boost_se_params_t_20 { typedef boost_se_capture_t_0_20 boost_se_param_t_0_20; typedef boost_se_capture_t_1_20 boost_se_param_t_1_20; boost::scope_exit::aux::member< boost_se_param_t_0_20, boost_se_tag_0_20 > boost_se_param_0_20; boost::scope_exit::aux::member< boost_se_param_t_1_20, boost_se_tag_1_20 > boost_se_param_1_20; } boost_local_auxXparams20 = { { boost::scope_exit::aux::deref(factor, (boost_se_tag_0_20)0) } , { boost::scope_exit::aux::deref(& sum, (boost_se_tag_1_20)0) } }; boost::scope_exit::aux::declared< boost::scope_
exit::aux::resolve< sizeof(boost_local_auxXargs) >::cmp1<0>::cmp2 > boost_local_auxXargs; boost_local_auxXargs.value = &boost_local_auxXparams20;
+
+
+ class boost_local_auxXfunctor20
+ //: public ::boost::local::aux::abstract_function< boost_local_auxXresult_type20 ( double num ), 0 >
+ {
+ //typedef boost_local_auxXresult_type20 (boost_local_auxXfunction_type) ( double num );
+ public:
+ explicit boost_local_auxXfunctor20(void* binding_data, double& _sum, int _factor)
+ : boost_local_auxXbinds(static_cast< boost_se_params_t_20*>(binding_data)) , sum_(_sum), factor_(_factor)
+ {
+ /*boost_local_auxXinit_recursion();*/
+// int f = 0;
+// sum_ = boost_local_auxXbinds-> boost_se_param_1_20.value;
+ factor_ = boost_local_auxXbinds-> boost_se_param_0_20.value;
+ std::cout << factor_ << std::endl;
+ }
+
+ void operator()( /*::boost::function_traits< boost_local_auxXfunction_type>::arg1_type*/double arg1 )
+ { return boost_local_auxXbody(
+ //boost_local_auxXbinds-> boost_se_param_0_20.value
+ 10//factor_
+ ,
+ //boost_local_auxXbinds-> boost_se_param_1_20.value
+ sum_
+ , arg1 );
+ }
+ private:
+// typedef ::boost::local::function<boost_local_auxXfunction_type, 0 > boost_local_auxXfunctor_type;
+// typedef ::boost::add_const< boost_se_params_t_20:: boost_se_param_t_0_20 >::type factorXboost_local_auxXtypeof_type ;
+// typedef boost_se_params_t_20:: boost_se_param_t_1_20 & sumXboost_local_auxXtypeof_type ;
+ boost_se_params_t_20* boost_local_auxXbinds;
+ double& sum_;
+ int factor_;
+// boost::scope_exit::aux::undeclared boost_local_auxXargs;
+
+ void boost_local_auxXbody(
+ /*::boost::add_const< boost_se_params_t_20:: boost_se_param_t_0_20 >::type*/const int factor
+ , /*boost_se_params_t_20:: boost_se_param_t_1_20*/double & sum , double num ) const {
+ sum += factor * num;
+ }
+// public:
+// boost_local_auxXfunctor_type add;
+// private:
+// void boost_local_auxXinit_recursion() {
+// //add = *this;
+// }
+ } boost_local_auxXfunctorXadd(boost_local_auxXargs.value, sum, factor);
+ // __typeof__(boost::type_of::ensure_obj(boost_local_auxXfunctorXadd.add)) const add(boost_local_auxXfunctorXadd);
+
+ for(int i = 0; i < 10000; ++i) {
+ for(size_t j = 0; j < v.size(); ++j) {
+ boost_local_auxXfunctorXadd(v[j]);
+ }
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/l03.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/l03.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,52 @@
+
+// Copyright (C) 2009-2011 Lorenzo Caminiti
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0 (see accompanying file LICENSE_1_0.txt or a
+// copy at http://www.boost.org/LICENSE_1_0.txt).
+
+#include <boost/local/function.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ std::vector<double> v(1000000);
+ std::fill(v.begin(), v.end(), 10);
+
+void (*ERROR_missing_result_type_before_the_local_function_parameter_macro_id20)(); typedef void (*boost_local_auxXdeduce_result_tag20)( int ERROR_missing_result_type_before_the_local_function_parameter_macro_id20); typedef __typeof__(boost::type_of::ensure_obj(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref( ERROR_missing_result_type_before_the_local_function_parameter_macro_id20, (boost_local_auxXdeduce_result_tag20)0)))) boost_local_auxXdeduce_result_wrap20; typedef boost_local_auxXdeduce_result_wrap20::type boost_local_auxXdeduce_result_capture20; struct boost_local_auxXdeduce_result_params20 { typedef boost_local_auxXdeduce_result_capture20 function_ptr_type; }; typedef boost::remove_pointer< boost_local_auxXdeduce_result_params20::function_ptr_type >::type boost_local_auxXdeduce_result_function_type20; typedef boost::function_traits< boost_local_auxXdeduce_result_function_type20>::result_type boost_local_auxXresult_type20; typedef void (*boost_se_tag_0_20)(int factor ); typedef void (*boos
t_se_tag_1_20)(int & sum ); typedef __typeof__(boost::type_of::ensure_obj(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref(factor, (boost_se_tag_0_20)0)))) boost_se_wrapped_t_0_20; typedef boost_se_wrapped_t_0_20::type boost_se_capture_t_0_20; typedef __typeof__(boost::type_of::ensure_obj(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref(& sum, (boost_se_tag_1_20)0)))) boost_se_wrapped_t_1_20; typedef boost_se_wrapped_t_1_20::type boost_se_capture_t_1_20; struct boost_se_params_t_20 { typedef boost_se_capture_t_0_20 boost_se_param_t_0_20; typedef boost_se_capture_t_1_20 boost_se_param_t_1_20; boost::scope_exit::aux::member< boost_se_param_t_0_20, boost_se_tag_0_20 > boost_se_param_0_20; boost::scope_exit::aux::member< boost_se_param_t_1_20, boost_se_tag_1_20 > boost_se_param_1_20; } boost_local_auxXparams20 = { { boost::scope_exit::aux::deref(factor, (boost_se_tag_0_20)0) } , { boost::scope_exit::aux::deref(& sum, (boost_se_tag_1_20)0) } }; boost::scope_exit::aux::declared< boost::scope_
exit::aux::resolve< sizeof(boost_local_auxXargs) >::cmp1<0>::cmp2 > boost_local_auxXargs; boost_local_auxXargs.value = &boost_local_auxXparams20;
+
+ std::cout << boost_local_auxXparams20.boost_se_param_0_20.value << std::endl;
+
+ class boost_local_auxXfunctor20 {
+ public:
+ explicit boost_local_auxXfunctor20(double& _sum, int _factor):
+ sum_(_sum), factor_(_factor) {
+ }
+ void operator()(double num) {
+ return boost_local_auxXbody(factor_, sum_, num);
+ }
+ private:
+ boost_se_params_t_20* boost_local_auxXbinds;
+ double& sum_;
+ int factor_;
+
+ void boost_local_auxXbody(const int factor, double & sum, double num)
+ const {
+ sum += factor * num;
+ }
+ } boost_local_auxXfunctorXadd(boost_local_auxXargs.value, sum, factor);
+
+
+ for(int i = 0; i < 10000; ++i) {
+ for(size_t j = 0; j < v.size(); ++j) {
+ boost_local_auxXfunctorXadd(v[j]);
+ }
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/l04.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/l04.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,51 @@
+
+// Copyright (C) 2009-2011 Lorenzo Caminiti
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0 (see accompanying file LICENSE_1_0.txt or a
+// copy at http://www.boost.org/LICENSE_1_0.txt).
+
+#include <boost/local/function.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ std::vector<double> v(1000000);
+ std::fill(v.begin(), v.end(), 10);
+
+
+void (*ERROR_missing_result_type_before_the_local_function_parameter_macro_id20)(); typedef void (*boost_local_auxXdeduce_result_tag20)( int ERROR_missing_result_type_before_the_local_function_parameter_macro_id20); typedef __typeof__(boost::type_of::ensure_obj(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref( ERROR_missing_result_type_before_the_local_function_parameter_macro_id20, (boost_local_auxXdeduce_result_tag20)0)))) boost_local_auxXdeduce_result_wrap20; typedef boost_local_auxXdeduce_result_wrap20::type boost_local_auxXdeduce_result_capture20; struct boost_local_auxXdeduce_result_params20 { typedef boost_local_auxXdeduce_result_capture20 function_ptr_type; }; typedef boost::remove_pointer< boost_local_auxXdeduce_result_params20::function_ptr_type >::type boost_local_auxXdeduce_result_function_type20; typedef boost::function_traits< boost_local_auxXdeduce_result_function_type20>::result_type boost_local_auxXresult_type20; typedef void (*boost_se_tag_0_20)(int factor ); typedef void (*boos
t_se_tag_1_20)(int & sum ); typedef __typeof__(boost::type_of::ensure_obj(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref(factor, (boost_se_tag_0_20)0)))) boost_se_wrapped_t_0_20; typedef boost_se_wrapped_t_0_20::type boost_se_capture_t_0_20; typedef __typeof__(boost::type_of::ensure_obj(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref(& sum, (boost_se_tag_1_20)0)))) boost_se_wrapped_t_1_20; typedef boost_se_wrapped_t_1_20::type boost_se_capture_t_1_20; struct boost_se_params_t_20 { typedef boost_se_capture_t_0_20 boost_se_param_t_0_20; typedef boost_se_capture_t_1_20 boost_se_param_t_1_20; boost::scope_exit::aux::member< boost_se_param_t_0_20, boost_se_tag_0_20 > boost_se_param_0_20; boost::scope_exit::aux::member< boost_se_param_t_1_20, boost_se_tag_1_20 > boost_se_param_1_20; } boost_local_auxXparams20 = { { boost::scope_exit::aux::deref(factor, (boost_se_tag_0_20)0) } , { boost::scope_exit::aux::deref(& sum, (boost_se_tag_1_20)0) } }; boost::scope_exit::aux::declared< boost::scope_
exit::aux::resolve< sizeof(boost_local_auxXargs) >::cmp1<0>::cmp2 > boost_local_auxXargs; boost_local_auxXargs.value = &boost_local_auxXparams20;
+
+ std::cout << boost_local_auxXparams20.boost_se_param_0_20.value << std::endl;
+
+ class local_add {
+ public:
+ explicit local_add(double& _sum, int _factor):
+ sum_(_sum), factor_(_factor) {
+ }
+ void operator()(double num) {
+ return body(factor_, sum_, num);
+ }
+ private:
+ double& sum_;
+ int factor_;
+
+ void body(const int factor, double& sum, double num)
+ const {
+ sum += factor * num;
+ }
+ } add(sum, factor);
+
+ for (size_t i = 0; i < 10000; ++i) {
+ for (size_t j = 0; j < v.size(); ++j) {
+ add(v[j]);
+ }
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/l05.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/l05.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,80 @@
+
+// Copyright (C) 2009-2011 Lorenzo Caminiti
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0 (see accompanying file LICENSE_1_0.txt or a
+// copy at http://www.boost.org/LICENSE_1_0.txt).
+
+#include <boost/local/function.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ std::vector<double> v(1000000);
+ std::fill(v.begin(), v.end(), 10);
+
+
+ //void (*ERROR_missing_result_type_before_the_local_function_parameter_macro_id20)(); typedef void (*boost_local_auxXdeduce_result_tag20)( int ERROR_missing_result_type_before_the_local_function_parameter_macro_id20); typedef __typeof__(boost::type_of::ensure_obj(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref( ERROR_missing_result_type_before_the_local_function_parameter_macro_id20, (boost_local_auxXdeduce_result_tag20)0)))) boost_local_auxXdeduce_result_wrap20; typedef boost_local_auxXdeduce_result_wrap20::type boost_local_auxXdeduce_result_capture20; struct boost_local_auxXdeduce_result_params20 { typedef boost_local_auxXdeduce_result_capture20 function_ptr_type; }; typedef boost::remove_pointer< boost_local_auxXdeduce_result_params20::function_ptr_type >::type boost_local_auxXdeduce_result_function_type20; typedef boost::function_traits< boost_local_auxXdeduce_result_function_type20>::result_type boost_local_auxXresult_type20;
+
+ typedef void (*boost_se_tag_0_20)(int factor);
+// typedef void (*boost_se_tag_1_20)(int & sum);
+
+ typedef BOOST_TYPEOF(boost::scope_exit::aux::wrap(
+ boost::scope_exit::aux::deref(factor, (boost_se_tag_0_20)0)))
+ boost_se_wrapped_t_0_20;
+ typedef boost_se_wrapped_t_0_20::type boost_se_capture_t_0_20;
+
+// typedef BOOST_TYPEOF(boost::scope_exit::aux::wrap(
+// boost::scope_exit::aux::deref(&sum, (boost_se_tag_1_20)0)))
+// boost_se_wrapped_t_1_20;
+// typedef boost_se_wrapped_t_1_20::type boost_se_capture_t_1_20;
+
+ struct boost_se_params_t_20 {
+ typedef boost_se_capture_t_0_20 boost_se_param_t_0_20;
+// typedef boost_se_capture_t_1_20 boost_se_param_t_1_20;
+
+ boost::scope_exit::aux::member<boost_se_param_t_0_20,
+ boost_se_tag_0_20> boost_se_param_0_20;
+// boost::scope_exit::aux::member<boost_se_param_t_1_20,
+// boost_se_tag_1_20> boost_se_param_1_20;
+ } boost_local_auxXparams20 = {
+ { boost::scope_exit::aux::deref(factor, (boost_se_tag_0_20)0) }
+// , { boost::scope_exit::aux::deref(& sum, (boost_se_tag_1_20)0) }
+ };
+ boost::scope_exit::aux::declared<boost::scope_exit::aux::resolve<
+ sizeof(boost_local_auxXargs)>::cmp1<0>::cmp2> boost_local_auxXargs;
+ boost_local_auxXargs.value = &boost_local_auxXparams20;
+
+ std::cout << boost_local_auxXparams20.boost_se_param_0_20.value << std::endl;
+
+ class local_add {
+ public:
+ explicit local_add(double& _sum, int _factor):
+ sum_(_sum), factor_(_factor) {
+ }
+ void operator()(double num) {
+ return body(factor_, sum_, num);
+ }
+ private:
+ double& sum_;
+ int factor_;
+
+ void body(const int factor, double& sum, double num)
+ const {
+ sum += factor * num;
+ }
+ } add(sum, factor);
+
+ for (size_t i = 0; i < 10000; ++i) {
+ for (size_t j = 0; j < v.size(); ++j) {
+ add(v[j]);
+ }
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/l06.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/l06.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,66 @@
+
+// Copyright (C) 2009-2011 Lorenzo Caminiti
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0 (see accompanying file LICENSE_1_0.txt or a
+// copy at http://www.boost.org/LICENSE_1_0.txt).
+
+#include <boost/local/function.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ std::vector<double> v(1000000);
+ std::fill(v.begin(), v.end(), 10);
+
+ typedef void (*boost_se_tag_0_20)(int factor);
+ typedef BOOST_TYPEOF(boost::scope_exit::aux::wrap(
+ boost::scope_exit::aux::deref(factor, (boost_se_tag_0_20)0)))
+ boost_se_wrapped_t_0_20;
+ typedef boost_se_wrapped_t_0_20::type boost_se_capture_t_0_20;
+
+ struct boost_se_params_t_20 {
+ typedef boost_se_capture_t_0_20 boost_se_param_t_0_20;
+
+ boost::scope_exit::aux::member<boost_se_param_t_0_20,
+ boost_se_tag_0_20> boost_se_param_0_20;
+ } boost_local_auxXparams20 = {
+ { boost::scope_exit::aux::deref(factor, (boost_se_tag_0_20)0) }
+ };
+ boost::scope_exit::aux::declared<boost::scope_exit::aux::resolve<
+ sizeof(boost_local_auxXargs)>::cmp1<0>::cmp2> boost_local_auxXargs;
+ boost_local_auxXargs.value = &boost_local_auxXparams20;
+
+ std::cout << boost_local_auxXparams20.boost_se_param_0_20.value << std::endl;
+
+ class local_add {
+ public:
+ explicit local_add(double& _sum, int _factor):
+ sum_(_sum), factor_(_factor) {
+ }
+ void operator()(double num) {
+ return body(factor_, sum_, num);
+ }
+ private:
+ double& sum_;
+ int factor_;
+
+ void body(const int factor, double& sum, double num)
+ const {
+ sum += factor * num;
+ }
+ } add(sum, factor);
+
+ for (size_t i = 0; i < 10000; ++i) {
+ for (size_t j = 0; j < v.size(); ++j) {
+ add(v[j]);
+ }
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/l07.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/l07.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,60 @@
+
+// Copyright (C) 2009-2011 Lorenzo Caminiti
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0 (see accompanying file LICENSE_1_0.txt or a
+// copy at http://www.boost.org/LICENSE_1_0.txt).
+
+#include <boost/local/function.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ std::vector<double> v(1000000);
+ std::fill(v.begin(), v.end(), 10);
+
+ typedef void (*tag)(int factor);
+ typedef BOOST_TYPEOF(boost::scope_exit::aux::wrap(
+ boost::scope_exit::aux::deref(factor, (tag)0))) wrapped_t;
+ typedef wrapped_t::type capture_t;
+
+ struct params_t {
+ typedef capture_t param_t;
+ boost::scope_exit::aux::member<param_t, tag> param;
+ } params = {
+ { boost::scope_exit::aux::deref(factor, (tag)0) }
+ };
+
+ std::cout << params.param.value << std::endl;
+
+ class local_add {
+ public:
+ explicit local_add(double& _sum, int _factor):
+ sum_(_sum), factor_(_factor) {
+ }
+ void operator()(double num) {
+ return body(factor_, sum_, num);
+ }
+ private:
+ double& sum_;
+ int factor_;
+
+ void body(const int factor, double& sum, double num)
+ const {
+ sum += factor * num;
+ }
+ } add(sum, 10);
+
+ for (size_t i = 0; i < 10000; ++i) {
+ for (size_t j = 0; j < v.size(); ++j) {
+ add(v[j]);
+ }
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/l08.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/l08.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,56 @@
+
+#include <boost/local/function.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ typedef void (*tag)(int factor);
+ typedef BOOST_TYPEOF(boost::scope_exit::aux::wrap(
+ boost::scope_exit::aux::deref(factor, (tag)0))) wrapped_t;
+ typedef wrapped_t::type capture_t;
+ struct params_t {
+ typedef capture_t param_t;
+ boost::scope_exit::aux::member<param_t, tag> param;
+ } params = {
+ { boost::scope_exit::aux::deref(factor, (tag)0) }
+ };
+
+
+ std::vector<double> v(1000000);
+ std::cout << params.param.value << std::endl;
+
+
+ class local_add {
+ public:
+ explicit local_add(double& _sum, int _factor):
+ sum_(_sum), factor_(_factor) {
+ }
+ void operator()(double num) {
+ return body(factor_, sum_, num);
+ }
+ private:
+ double& sum_;
+ int factor_;
+
+ void body(const int factor, double& sum, double num)
+ const {
+ sum += factor * num;
+ }
+ } add(sum, factor);
+
+ std::fill(v.begin(), v.end(), 10);
+ for (size_t i = 0; i < 10000; ++i) {
+ for (size_t j = 0; j < v.size(); ++j) {
+ //add(v[j]);
+ add(10);
+ }
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/l09.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/l09.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,55 @@
+
+#include <boost/local/function.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ typedef void (*tag)(int factor);
+ typedef BOOST_TYPEOF(boost::scope_exit::aux::wrap(
+ boost::scope_exit::aux::deref(factor, (tag)0))) wrapped_t;
+ typedef wrapped_t::type capture_t;
+ struct params_t {
+ typedef capture_t param_t;
+ boost::scope_exit::aux::member<param_t, tag> param;
+ } params = {
+ { boost::scope_exit::aux::deref(factor, (tag)0) }
+ };
+
+
+ std::cout << params.param.value << std::endl;
+ std::vector<double> v(1000000);
+
+
+ class local_add {
+ public:
+ explicit local_add(double& _sum, int _factor):
+ sum_(_sum), factor_(_factor) {
+ }
+ void operator()(double num) {
+ return body(factor_, sum_, num);
+ }
+ private:
+ double& sum_;
+ int factor_;
+
+ void body(const int factor, double& sum, double num)
+ const {
+ sum += factor * num;
+ }
+ } add(sum, factor);
+
+ std::fill(v.begin(), v.end(), 10);
+ for (size_t i = 0; i < 10000; ++i) {
+ for (size_t j = 0; j < v.size(); ++j) {
+ add(v[j]);
+ }
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/l10.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/l10.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,60 @@
+
+#include <boost/local/function.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+// typedef void (*tag)(int factor);
+// typedef BOOST_TYPEOF(boost::scope_exit::aux::wrap(
+// boost::scope_exit::aux::deref(factor, (tag)0))) wrapped_t;
+// typedef wrapped_t::type capture_t;
+// struct params_t {
+// typedef capture_t param_t;
+// boost::scope_exit::aux::member<param_t, tag> param;
+// } params = {
+//#ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
+// {
+//#endif
+// boost::scope_exit::aux::deref(factor, (tag)0)
+//#ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
+// }
+//#endif
+// };
+
+// std::vector<double> v(1000000);
+// std::cout << params.param.value << std::endl;
+
+
+ class local_add {
+ public:
+ explicit local_add(double& _sum):
+ sum_(_sum) {
+ }
+ void operator()(double num) {
+ return body(sum_, num);
+ }
+ private:
+ double& sum_;
+
+ void body(double& sum, double num)
+ const {
+ sum += 10 * num;
+ }
+ } add(sum);
+
+ //std::fill(v.begin(), v.end(), 10);
+ for (size_t i = 0; i < 10000; ++i) {
+ for (size_t j = 0; j < 1000000; ++j) {
+ //add(v[j]);
+ add(10);
+ }
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/p00.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/p00.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,28 @@
+
+// Copyright (C) 2009-2011 Lorenzo Caminiti
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0 (see accompanying file LICENSE_1_0.txt or a
+// copy at http://www.boost.org/LICENSE_1_0.txt).
+
+#include <boost/spirit/include/phoenix.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ std::vector<double> v(1000000);
+ std::fill(v.begin(), v.end(), 10);
+
+ for(int i = 0; i < 10000; ++i) {
+ std::for_each(v.begin(), v.end(), (
+ boost::phoenix::ref(sum) += factor * boost::phoenix::arg_names::_1
+ ));
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/tom_add_boost_local.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/tom_add_boost_local.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,25 @@
+
+#include <boost/local/function.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ void BOOST_LOCAL_FUNCTION_PARAMS( (const double& num)
+ (bind& sum) (const bind& factor) ) {
+ sum += factor * num;
+ } BOOST_LOCAL_FUNCTION_NAME(add)
+
+ std::vector<double> v(1000000);
+ std::fill(v.begin(), v.end(), 10);
+ for (size_t i = 0; i < 10000; ++i) {
+ std::for_each(v.begin(), v.end(), add);
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/tom_add_boost_phoenix.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/tom_add_boost_phoenix.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,25 @@
+
+#include <boost/spirit/include/phoenix.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ std::vector<double> v(1000000);
+
+ std::fill(v.begin(), v.end(), 10);
+
+ for(int i = 0; i < 10000; ++i)
+ {
+ std::for_each(v.begin(), v.end(), (
+ boost::phoenix::ref(sum) += factor * boost::phoenix::arg_names::_1
+ ));
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/tom_local.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/tom_local.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,26 @@
+
+#include <boost/local/function.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ void BOOST_LOCAL_FUNCTION_PARAMS( (double num)
+ (bind& sum) (const bind factor) ) {
+ sum += factor * num;
+ } BOOST_LOCAL_FUNCTION_NAME(add)
+
+ std::vector<double> v(100000);
+ std::fill(v.begin(), v.end(), 10);
+
+ for (size_t i = 0; i < 10000; ++i) {
+ std::for_each(v.begin(), v.end(), add);
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/tom_phoenix.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/tom_phoenix.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,23 @@
+
+#include <boost/spirit/include/phoenix.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ std::vector<double> v(100000);
+ std::fill(v.begin(), v.end(), 10);
+
+ for (size_t i = 0; i < 10000; ++i) {
+ std::for_each(v.begin(), v.end(), (
+ boost::phoenix::ref(sum) += factor * boost::phoenix::arg_names::_1
+ ));
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/tparam_trick.00.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/tparam_trick.00.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,51 @@
+
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+#define N 10000
+
+struct abstract_function {
+ virtual void operator()() = 0;
+};
+
+struct function {
+ function(abstract_function& ref): ptr_(&ref) {}
+ void operator()() { return ptr_->operator()(); }
+private:
+ abstract_function* ptr_;
+};
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ struct add_function: abstract_function {
+ add_function(double& _sum, const int& _factor):
+ sum_(_sum), factor_(_factor) {}
+ void operator()() { return body(sum_, factor_); }
+ private:
+ double& sum_;
+ const int& factor_;
+ void body(double& sum, const int& factor) {
+ sum += factor * 10;
+ }
+ };
+ add_function functor_add(sum, factor);
+ function add(functor_add);
+
+ std::vector<double> v(N * 100);
+ std::fill(v.begin(), v.end(), 10);
+
+ for (size_t n = 0; n < N; ++n) {
+ for (size_t i = 0; i < v.size(); ++i) {
+// functor_add(v[i]); // (1)
+ add(); // (2)
+ }
+ // std::for_each(v.begin(), v.end(), add); // (3) OK add as tparam!
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/tparam_trick.01.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/tparam_trick.01.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,54 @@
+
+#include <boost/function.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+#define N 10000
+
+struct abstract_function {
+ virtual void operator()() = 0;
+};
+
+struct function {
+ function(abstract_function& ref): ptr_(&ref) {}
+ void operator()() { return ptr_->operator()(); }
+private:
+ abstract_function* ptr_;
+};
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ struct add_function: abstract_function {
+ add_function(double& _sum, const int& _factor):
+ sum_(_sum), factor_(_factor) {}
+ void operator()() { return body(sum_, factor_); }
+ static void f(const double& x) {}
+ double& sum_;
+ const int& factor_;
+ void body(double& sum, const int& factor) {
+ sum += factor * 10;
+ }
+ };
+ add_function functor_add(sum, factor);
+// boost::function<void ()> add(functor_add);
+ void (add_function::*f)() = add_function::operator();
+ functor_addf();
+
+ std::vector<double> v(N * 100);
+ std::fill(v.begin(), v.end(), 10);
+
+ for (size_t n = 0; n < N; ++n) {
+ for (size_t i = 0; i < v.size(); ++i) {
+// functor_add(v[i]); // (1)
+ f(10); // (2)
+ }
+// std::for_each(v.begin(), v.end(), f); // (3) OK add as tparam!
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/tparam_trick.02.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/tparam_trick.02.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,73 @@
+
+//#include <boost/spirit/include/phoenix.hpp>
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+#include <cassert>
+
+#define N 10000
+
+struct abstract_function {
+ virtual void operator()(const double&) = 0;
+};
+
+struct function {
+ function(void* obj, void (*call)(void*, const double&)):
+ obj_(obj), call_(call) {}
+ inline void operator()(const double& arg1) { call_(obj_, arg1); }
+private:
+ void* obj_;
+ void (*call_)(void*, const double&);
+};
+
+void call(void* obj, const double& num) {}
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ struct add_function: abstract_function {
+ add_function(double& _sum, const int& _factor):
+ sum_(_sum), factor_(_factor) {}
+ void operator()(const double& num) { body(sum_, factor_, num); }
+ static void call(void* obj, const double& num) {
+ static_cast<add_function*>(obj)->operator()(num);
+// add_function* self = static_cast<add_function*>(obj);
+// return self->body(self->sum_, self->factor_, num);
+ }
+ private:
+ double& sum_;
+ const int& factor_;
+ void body(double& sum, const int& factor, const double& num) {
+ sum += factor * num;
+ }
+ };
+ add_function adder(sum, factor);
+ function add(&adder, &add_function::call);
+
+ std::vector<double> v(N * 100);
+ std::fill(v.begin(), v.end(), 10);
+
+ for (size_t n = 0; n < N; ++n) {
+ for (size_t i = 0; i < v.size(); ++i) {
+// adder(v[i]); // (1)
+// add_function::call(&adder, v[i]);
+// add(v[i]);
+ boost::bind(add_function::call, (void*)&adder, _1)(v[i]);
+// v[i];
+// add(); // (2)
+// add_function::call(&adder);
+// add(v[i]);
+ }
+// std::for_each(v.begin(), v.end(), add); // (3) OK add as tparam!
+// std::for_each(v.begin(), v.end(),
+// boost::phoenix::val(adder.f(10))
+// );
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/tparam_trick.03.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/tparam_trick.03.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,69 @@
+
+#include <iostream>
+#include <vector>
+#include <algorithm>
+#include <cassert>
+
+#define N 10000
+
+struct base_function {
+ virtual void operator()(const double&) {
+ std::cout << "parent\n";
+ }
+};
+
+struct function {
+ function(void* obj, void (*call)(void*, const double&)):
+ obj_(obj), call_(call) {}
+ inline void operator()(const double& arg1) {
+ call_(obj_, arg1);
+ }
+private:
+ void* obj_;
+ void (*call_)(void*, const double&);
+};
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ struct local_add: base_function {
+ local_add(double& _sum, const int& _factor):
+ sum_(_sum), factor_(_factor) {}
+ void operator()(const double& num) { body(sum_, factor_, num); }
+ static void call(void* obj, const double& num)
+ { static_cast<local_add*>(obj)->operator()(num); }
+ private:
+ double& sum_;
+ const int& factor_;
+ void body(double& sum, const int& factor, const double& num) {
+ sum += factor * num;
+ }
+ };
+ local_add add_l(sum, factor);
+ base_function& add_b = add_l;
+ function add_f(&add_l, local_add::call);
+
+ void* obj_ = &add_l;
+ register void (*call_)(void*, const double&) = &local_add::call;
+
+ std::vector<double> v(N * 100);
+ std::fill(v.begin(), v.end(), 10);
+
+ for (size_t n = 0; n < N; ++n) {
+// std::for_each(v.begin(), v.end(), add_l); // Error.
+// std::for_each(v.begin(), v.end(), add_b);
+// std::for_each(v.begin(), v.end(), add_f);
+ for (size_t i = 0; i < v.size(); ++i) {
+// add_l(v[i]);
+// add_b(v[i]);
+// add_f(v[i]);
+// local_add::call(&add_l, v[i]);
+ call_(obj_, v[i]);
+ }
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/tparam_trick.04.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/tparam_trick.04.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,53 @@
+
+#include <iostream>
+#include <vector>
+#include <algorithm>
+#include <cassert>
+
+#define N 10000
+
+//struct func {
+// func(void* obj, void (*call)(void*, const double&)):
+// obj_(obj), call_(call) {}
+// inline void operator()(const double& num) { call_(obj_, num); }
+//private:
+// void* obj_;
+// void (*call_)(void*, const double&);
+};
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ struct local_add {
+ local_add(double& _sum, const int& _factor):
+ sum_(_sum), factor_(_factor) {}
+ void operator()(const double& num) { body(sum_, factor_, num); }
+ static void call(void* obj, const double& num)
+ { static_cast<local_add*>(obj)->operator()(num); }
+ private:
+ double& sum_;
+ const int& factor_;
+ void body(double& sum, const int& factor, const double& num) {
+ sum += factor * num;
+ }
+ };
+ local_add add_l(sum, factor);
+ void* obj_ = &add_l;
+ void (*call_)(void*, const double&) = &local_add::call;
+// func add_f(&add_l, &local_add::call);
+
+ std::vector<double> v(N);
+ std::fill(v.begin(), v.end(), 10);
+
+ for (size_t n = 0; n < N; ++n) {
+ for (size_t i = 0; i < v.size(); ++i) {
+// local_add::call(&add_l, v[i]); // (1) runs in 16s
+ call_(obj_, v[i]); // (2) runs in 16s
+ }
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/tparam_trick.05.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/tparam_trick.05.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,43 @@
+
+#include <iostream>
+#include <vector>
+#include <algorithm>
+#include <cassert>
+
+#define N 10000
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ struct local_add {
+ local_add(double& _sum, const int& _factor):
+ sum_(_sum), factor_(_factor) {}
+ void operator()(const double& num) { body(sum_, factor_, num); }
+ static void call(void* obj, const double& num)
+ { static_cast<local_add*>(obj)->operator()(num); }
+ private:
+ double& sum_;
+ const int& factor_;
+ void body(double& sum, const int& factor, const double& num) {
+ sum += factor * num;
+ }
+ };
+ local_add add_l(sum, factor);
+ void* obj_ = &add_l;
+ void (*call_)(void*, const double&) = &local_add::call;
+
+ std::vector<double> v(N * 100);
+ std::fill(v.begin(), v.end(), 10);
+
+ for (size_t n = 0; n < N; ++n) {
+ for (size_t i = 0; i < v.size(); ++i) {
+// local_add::call(&add_l, v[i]); // (1) runs in 16s
+ call_(obj_, v[i]); // (2) runs in
+ }
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/tparam_trick.06.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/tparam_trick.06.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,54 @@
+
+#include <iostream>
+#include <vector>
+#include <algorithm>
+#include <cassert>
+
+#define N 10000
+
+struct func {
+ func(void* obj, void (*call)(void*, const double&)):
+ obj_(obj), call_(call) {}
+ inline void operator()(const double& num) { call_(obj_, num); }
+private:
+ void* obj_;
+ void (*call_)(void*, const double&);
+};
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ struct local_add {
+ local_add(double& _sum, const int& _factor):
+ sum_(_sum), factor_(_factor) {}
+ void operator()(const double& num) { body(sum_, factor_, num); }
+ static void call(void* obj, const double& num)
+ { static_cast<local_add*>(obj)->operator()(num); }
+ private:
+ double& sum_;
+ const int& factor_;
+ void body(double& sum, const int& factor, const double& num) {
+ sum += factor * num;
+ }
+ };
+ local_add add_l(sum, factor);
+ void* obj_ = &add_l;
+ void (*call_)(void*, const double&) = &local_add::call;
+ func add_f(&add_l, &local_add::call);
+
+ std::vector<double> v(N * 10);
+ std::fill(v.begin(), v.end(), 10);
+
+ for (size_t n = 0; n < N; ++n) {
+ for (size_t i = 0; i < v.size(); ++i) {
+// local_add::call(&add_l, v[i]); // (1) runs in 19s
+// call_(obj_, v[i]); // (2) runs in 20s
+// add_f(v[i]); // (3) runs in 23s
+ }
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/tparam_trick.07.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/tparam_trick.07.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,67 @@
+
+#include <iostream>
+#include <vector>
+#include <algorithm>
+#include <cassert>
+
+#define N 10000
+
+struct abstract_func {
+ virtual void operator()(const double&) = 0;
+};
+
+struct virtual_func {
+ virtual_func(abstract_func& ref): ptr_(&ref) {}
+ inline void operator()(const double& num) { (*ptr_)(num); }
+private:
+ abstract_func* ptr_;
+};
+
+struct casting_func {
+ casting_func(void* obj, void (*call)(void*, const double&)):
+ obj_(obj), call_(call) {}
+ inline void operator()(const double& num) { call_(obj_, num); }
+private:
+ void* obj_;
+ void (*call_)(void*, const double&);
+};
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ struct local_add: abstract_func {
+ local_add(double& _sum, const int& _factor):
+ sum_(_sum), factor_(_factor) {}
+ void operator()(const double& num) { body(sum_, factor_, num); }
+ static void call(void* obj, const double& num)
+ { static_cast<local_add*>(obj)->operator()(num); }
+ private:
+ double& sum_;
+ const int& factor_;
+ void body(double& sum, const int& factor, const double& num) {
+ sum += factor * num;
+ }
+ };
+ local_add add_l(sum, factor);
+ void* obj_ = &add_l;
+ void (*call_)(void*, const double&) = &local_add::call;
+ casting_func add_c(&add_l, &local_add::call);
+ virtual_func add_v(add_l);
+
+ std::vector<double> v(N * 10);
+ std::fill(v.begin(), v.end(), 10);
+
+ for (size_t n = 0; n < N; ++n) {
+ for (size_t i = 0; i < v.size(); ++i) {
+// local_add::call(&add_l, v[i]); // (1) runs in 19s
+// call_(obj_, v[i]); // (2) runs in 20s
+// add_c(v[i]); // (3) runs in 23s (or 25s w/ abstract_func base)
+ add_v(v[i]); // (4) runs in 21s
+ }
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/tparam_trick.08.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/tparam_trick.08.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,72 @@
+
+#include <iostream>
+#include <vector>
+#include <algorithm>
+#include <cassert>
+
+#define N 1e4
+#define S N * 1e2
+
+struct func_if {
+ inline virtual void operator()(const double&) = 0;
+};
+
+struct virtual_func {
+ explicit virtual_func(func_if& ref): ptr_(&ref) {}
+ inline void operator()(const double& num) { (*ptr_)(num); }
+private:
+ func_if* ptr_;
+};
+
+struct casting_func {
+ explicit casting_func(void* obj, void (*call)(void*, const double&)):
+ obj_(obj), call_(call) {}
+ inline void operator()(const double& num) { call_(obj_, num); }
+private:
+ void* obj_;
+ void (*call_)(void*, const double&);
+};
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ struct local_add: func_if {
+ explicit local_add(double& _sum, const int& _factor):
+ sum_(_sum), factor_(_factor) {}
+ inline void operator()(const double& num) { body(sum_, factor_, num); }
+ inline static void call(void* obj, const double& num) {
+ local_add* self = static_cast<local_add*>(obj);
+ self->body(self->sum_, self->factor_, num);
+ }
+ private:
+ double& sum_;
+ const int& factor_;
+ inline void body(double& sum, const int& factor, const double& num) {
+ sum += factor * num;
+ }
+ };
+ local_add add_local(sum, factor);
+
+ void* obj = &add_local;
+ void (*call)(void*, const double&) = &local_add::call;
+
+ casting_func add_casting(&add_local, &local_add::call);
+ virtual_func add_virtual(add_local);
+
+ std::vector<double> v(S);
+ std::fill(v.begin(), v.end(), 10);
+
+ for (size_t n = 0; n < N; ++n) {
+ for (size_t i = 0; i < v.size(); ++i) {
+// local_add::call(&add_local, v[i]); // (1) runs in 19s
+// call(obj, v[i]); // (2) runs in 20s
+// add_casting(v[i]); // (3) runs in 23s (or 25s w/ func_if base)
+ add_virtual(v[i]); // (4) runs in 21s
+ }
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/tparam_trick.09.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/tparam_trick.09.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,91 @@
+
+// Tricks to "pass" a local class as a template parameter.
+
+// compile-time: $ time g++ -O3 -Wall <THIS_FILE>
+// run-time: $ time ./a
+
+#include <iostream>
+#include <vector>
+#include <algorithm>
+#include <cassert>
+
+#define N 1e4
+#define S N * 1e2
+
+// Trick A: Virtual Base
+
+struct func_if {
+ inline virtual void __attribute__((always_inline)) operator()(
+ const double&) {} // virtual call cannot be inlined
+};
+
+struct virtual_func {
+ explicit virtual_func(func_if& ref): ptr_(&ref) {}
+ inline void __attribute__((always_inline)) operator()(const double& num)
+ { (*ptr_)(num); }
+private:
+ func_if* ptr_;
+};
+
+// Trick B: Casting Function Pointer
+
+struct casting_func {
+ explicit casting_func(void* obj, void (*call)(void*, const double&)):
+ obj_(obj), call_(call) {}
+ inline void __attribute__((always_inline)) operator()(const double& num)
+ { call_(obj_, num); } // function pointer call cannot be inlined
+private:
+ void* obj_;
+ void (*call_)(void*, const double&);
+};
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ struct local_add
+ : func_if
+ {
+ explicit local_add(double& _sum, const int& _factor):
+ sum_(_sum), factor_(_factor) {}
+ inline void __attribute__((always_inline)) operator()(
+ const double& num) { body(sum_, factor_, num); }
+// inline static void __attribute__((always_inline)) call(
+// void* obj, const double& num) {
+// local_add* self = static_cast<local_add*>(obj);
+// self->body(self->sum_, self->factor_, num);
+// }
+ private:
+ double& sum_;
+ const int& factor_;
+ inline void __attribute__((always_inline)) body(
+ double& sum, const int& factor, const double& num) {
+ sum += factor * num;
+ }
+ };
+ local_add add_local(sum, factor);
+
+// void* obj = &add_local;
+// void (*call)(void*, const double&) = &local_add::call;
+
+// casting_func add_casting(&add_local, &local_add::call);
+ virtual_func add_virtual(add_local);
+
+ std::vector<double> v(S);
+ std::fill(v.begin(), v.end(), 10);
+
+ for (size_t n = 0; n < N; ++n) {
+// for (size_t i = 0; i < v.size(); ++i) {
+// add_local(v[i]); // (1) runs in 16s
+// call(obj, v[i]); // (2) runs in 16s
+// add_casting(v[i]); // (3) runs in 40s
+// add_virtual(v[i]); // (4) runs in 47s
+// }
+ std::for_each(v.begin(), v.end(), add_casting); // (5) runs in 40s
+// std::for_each(v.begin(), v.end(), add_virtual); // (6) runs in 46s
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/tparam_trick.10.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/tparam_trick.10.cpp 2011-04-07 16:41:00 EDT (Thu, 07 Apr 2011)
@@ -0,0 +1,91 @@
+
+// Tricks to "pass" a local class as a template parameter.
+
+// compile-time: $ time g++ -O3 -Wall <THIS_FILE>
+// run-time: $ time ./a
+
+#include <iostream>
+#include <vector>
+#include <algorithm>
+#include <cassert>
+
+#define N 1e4
+#define S N * 1e2
+
+// Trick A: Virtual Base
+
+struct func_if {
+ inline virtual void operator()(
+ const double&) {} // virtual call cannot be inlined
+};
+
+struct virtual_func {
+ explicit virtual_func(func_if& ref): ptr_(&ref) {}
+ inline void operator()(const double& num)
+ { (*ptr_)(num); }
+private:
+ func_if* ptr_;
+};
+
+// Trick B: Casting Function Pointer
+
+struct casting_func {
+ explicit casting_func(void* obj, void (*call)(void*, const double&)):
+ obj_(obj), call_(call) {}
+ inline void operator()(const double& num)
+ { call_(obj_, num); } // function pointer call cannot be inlined
+private:
+ void* obj_;
+ void (*call_)(void*, const double&);
+};
+
+int main() {
+ double sum = 0.0;
+ int factor = 10;
+
+ struct local_add
+// : func_if
+ {
+ explicit local_add(double& _sum, const int& _factor):
+ sum_(_sum), factor_(_factor) {}
+// inline void operator()(
+// const double& num) { body(sum_, factor_, num); }
+ inline static void call(
+ void* obj, const double& num) {
+ local_add* self = static_cast<local_add*>(obj);
+ self->body(self->sum_, self->factor_, num);
+ }
+ private:
+ double& sum_;
+ const int& factor_;
+ inline void body(
+ double& sum, const int& factor, const double& num) {
+ sum += factor * num;
+ }
+ };
+ local_add add_local(sum, factor);
+
+// void* obj = &add_local;
+// void (*call)(void*, const double&) = &local_add::call;
+
+ casting_func add_casting(&add_local, &local_add::call);
+// virtual_func add_virtual(add_local);
+
+ std::vector<double> v(S);
+ std::fill(v.begin(), v.end(), 10);
+
+ for (size_t n = 0; n < N; ++n) {
+// for (size_t i = 0; i < v.size(); ++i) {
+// add_local(v[i]); // (1) runs in 16s
+// call(obj, v[i]); // (2) runs in 16s
+// add_casting(v[i]); // (3) runs in 40s
+// add_virtual(v[i]); // (4) runs in 47s
+// }
+ std::for_each(v.begin(), v.end(), add_casting); // (5) runs in 40s(40s)
+// std::for_each(v.begin(), v.end(), add_virtual); // (6) runs in 46s(42s)
+ }
+
+ std::cout << sum << std::endl;
+ return 0;
+}
+


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk