Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r71225 - in sandbox/local: boost/local/aux_ libs/local/example
From: lorcaminiti_at_[hidden]
Date: 2011-04-13 11:36:40


Author: lcaminiti
Date: 2011-04-13 11:36:37 EDT (Wed, 13 Apr 2011)
New Revision: 71225
URL: http://svn.boost.org/trac/boost/changeset/71225

Log:
Improved performance (run-time of 22s using MSVC on Cygwin).
Added:
   sandbox/local/boost/local/aux_/config.hpp (contents, props changed)
   sandbox/local/libs/local/example/optim.02.cpp (contents, props changed)
   sandbox/local/libs/local/example/optim.03.cpp (contents, props changed)
   sandbox/local/libs/local/example/optim.04.cpp (contents, props changed)
   sandbox/local/libs/local/example/optim.05.cpp (contents, props changed)
   sandbox/local/libs/local/example/optim.06.cpp (contents, props changed)

Added: sandbox/local/boost/local/aux_/config.hpp
==============================================================================
--- (empty file)
+++ sandbox/local/boost/local/aux_/config.hpp 2011-04-13 11:36:37 EDT (Wed, 13 Apr 2011)
@@ -0,0 +1,16 @@
+
+#ifndef BOOST_LOCAL_AUX_CONFIG_HPP_
+#define BOOST_LOCAL_AUX_CONFIG_HPP_
+
+#include "../config.hpp"
+
+// If it is possible to pass a local class as a template parameter. This is
+// not possible on ISO C++ but it is possible on C++03 extensions, MSVC, etc.
+#if !defined(BOOST_LOCAL_CONFIG_COMPLIANT) && defined(_MSC_VER)
+# define BOOST_LOCAL_AUX_CONFIG_LOCAL_CLASS_AS_TEMPLATE_PARAMETER
+#else
+# undef BOOST_LOCAL_AUX_CONFIG_LOCAL_CLASS_AS_TEMPLATE_PARAMETER
+#endif
+
+#endif // #include guard
+

Added: sandbox/local/libs/local/example/optim.02.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/optim.02.cpp 2011-04-13 11:36:37 EDT (Wed, 13 Apr 2011)
@@ -0,0 +1,164 @@
+
+#include <boost/local/function.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+#include <cassert>
+
+// This is a non-local functor so it can be passed as template parameter.
+// obj will be of local class type so it cannot be passed as template param (it is instead handled as a generic void pointer and the call function will cast it).
+template< typename R, typename A0, size_t defaults >
+class casting_function {
+ typedef R (*call_function)(void* obj, A0);
+public:
+ // public
+ explicit casting_function(void* obj = 0, call_function call = 0): obj_(obj), call_(call) {}
+ /* implicit for GCC */ casting_function(casting_function const& other): obj_(other.obj_), call_(other.call_) {}
+ // precondition: set
+ inline void operator()(A0 num) { call_(obj_, num); } // function pointer call cannot be inlined
+ // private
+ inline void set(void* obj = 0, call_function call = 0) { obj_ = obj; call_ = call; }
+private:
+ void* obj_;
+ call_function call_;
+};
+
+int main() {
+ double sum = 0.0;
+ int factor = 1;
+
+ void (*ERROR_missing_result_type_before_the_local_function_parameter_macro_id19)(); typedef void (*boost_local_auxXdeduce_result_tag19)( int ERROR_missing_result_type_before_the_local_function_parameter_macro_id19);
+ typedef BOOST_TYPEOF(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref( ERROR_missing_result_type_before_the_local_function_parameter_macro_id19, (boost_local_auxXdeduce_result_tag19)0))) boost_local_auxXdeduce_result_wrap19;
+ typedef boost_local_auxXdeduce_result_wrap19::type boost_local_auxXdeduce_result_capture19;
+ struct boost_local_auxXdeduce_result_params19 { typedef boost_local_auxXdeduce_result_capture19 function_ptr_type; };
+ typedef boost::remove_pointer< boost_local_auxXdeduce_result_params19::function_ptr_type >::type boost_local_auxXdeduce_result_function_type19;
+ typedef boost::function_traits< boost_local_auxXdeduce_result_function_type19>::result_type boost_local_auxXresult_type19;
+ typedef void (*boost_se_tag_0_19)(int & factor );
+ typedef void (*boost_se_tag_1_19)(int & sum );
+ typedef BOOST_TYPEOF(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref(& factor, (boost_se_tag_0_19)0))) boost_se_wrapped_t_0_19;
+ typedef boost_se_wrapped_t_0_19::type boost_se_capture_t_0_19;
+ typedef BOOST_TYPEOF(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref(& sum, (boost_se_tag_1_19)0))) boost_se_wrapped_t_1_19;
+ typedef boost_se_wrapped_t_1_19::type boost_se_capture_t_1_19;
+ struct boost_se_params_t_19 {
+ typedef boost_se_capture_t_0_19 boost_se_param_t_0_19;
+ typedef boost_se_capture_t_1_19 boost_se_param_t_1_19;
+ boost::scope_exit::aux::member< boost_se_param_t_0_19, boost_se_tag_0_19 > boost_se_param_0_19;
+ boost::scope_exit::aux::member< boost_se_param_t_1_19, boost_se_tag_1_19 > boost_se_param_1_19;
+ } boost_local_auxXparams19 = {
+#ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
+ {
+#endif
+ boost::scope_exit::aux::deref(& factor, (boost_se_tag_0_19)0)
+#ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
+ }
+#endif
+ ,
+#ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
+ {
+#endif
+ boost::scope_exit::aux::deref(& sum, (boost_se_tag_1_19)0)
+#ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
+ }
+#endif
+ };
+ 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_auxXparams19;
+
+ class boost_local_auxXfunctor19
+ : public ::boost::local::aux::abstract_function< boost_local_auxXresult_type19 ( const double& num ), 0 >
+ {
+ typedef boost_local_auxXresult_type19 (boost_local_auxXfunction_type) ( const double& num );
+ public:
+ explicit boost_local_auxXfunctor19(void* binding_data):
+ boost_local_auxXbinds(static_cast< boost_se_params_t_19*>(binding_data))
+ , factor(boost_local_auxXbinds->boost_se_param_0_19.value)
+ , sum(boost_local_auxXbinds-> boost_se_param_1_19.value)
+ {
+ boost_local_auxXinit_recursion();
+ }
+ boost_local_auxXresult_type19 operator()(::boost::call_traits< ::boost::function_traits<boost_local_auxXfunction_type>::arg1_type>::param_type arg1) {
+ return boost_local_auxXbody(arg1);
+ }
+ private:
+ typedef ::boost::local::function<boost_local_auxXfunction_type, 0 > boost_local_auxXfunctor_type;
+ typedef ::boost::add_const< boost_se_params_t_19:: boost_se_param_t_0_19 >::type & factorXboost_local_auxXtypeof_type ;
+ typedef boost_se_params_t_19:: boost_se_param_t_1_19 & sumXboost_local_auxXtypeof_type ;
+ boost_se_params_t_19* boost_local_auxXbinds;
+ boost::scope_exit::aux::undeclared boost_local_auxXargs;
+
+ ::boost::add_const< boost_se_params_t_19:: boost_se_param_t_0_19 >::type & factor;
+ boost_se_params_t_19:: boost_se_param_t_1_19 & sum;
+
+ boost_local_auxXresult_type19 boost_local_auxXbody(const double& num) const {
+ sum += factor * num;
+ }
+
+ private:
+ boost_local_auxXfunctor_type add;
+ private:
+ void boost_local_auxXinit_recursion() { add = *this; }
+ } add_bl(boost_local_auxXargs.value);
+ ::boost::local::function< boost_local_auxXresult_type19 ( const double& num ), 0 > add_f(add_bl);
+
+ class local_add
+// Cannot use virtual-base trick because it prevents optimizations also when passing the local functor as template param on C++03.
+// Use casting trick instead to allow for C++03 optimizations.
+// : public ::boost::local::aux::abstract_function<boost_local_auxXresult_type19 (const double& num), 0>
+ {
+ // Function and functor types.
+ typedef boost_local_auxXresult_type19 (boost_local_auxXfunction_type) (const double& num);
+ typedef casting_function< boost_local_auxXresult_type19, const double&, 0 > casting_function_type;
+ // For local-typeof.
+ typedef ::boost::add_const< boost_se_params_t_19:: boost_se_param_t_0_19 >::type & factorXboost_local_auxXtypeof_type ;
+ typedef boost_se_params_t_19:: boost_se_param_t_1_19 & sumXboost_local_auxXtypeof_type ;
+ public:
+ explicit local_add(void* binds):
+ bind1(static_cast< boost_se_params_t_19* >(binds)->boost_se_param_0_19.value)
+ , bind2(static_cast< boost_se_params_t_19* >(binds)->boost_se_param_1_19.value)
+ {}
+ // Leave here even if call is used so this class can be used as functor for C++03 optimizations.
+ inline boost_local_auxXresult_type19 operator()(const double& num) {
+ return body(
+ //boost_local_auxXbinds-> boost_se_param_0_19.value, boost_local_auxXbinds-> boost_se_param_1_19.value
+ bind1, bind2
+ , num);
+ }
+ // To pass local function as tparam on non C++03.
+ inline static boost_local_auxXresult_type19 call(void* obj, const double& num) {
+ return static_cast<local_add*>(obj)->operator()(num);
+ }
+ private:
+ // Use binds as single mem vars instead of accessing `boost_se_params_t_19* boost_local_auxXbinds` all the times improves performance.
+ // Always add ref because these data must just reference the actual data stored in the params struct declared outside this class (and passed to the ctor by
+ // ptr).
+ ::boost::add_const< boost_se_params_t_19:: boost_se_param_t_0_19 >::type & bind1;
+ boost_se_params_t_19:: boost_se_param_t_1_19 & bind2;
+ // For nesting.
+ boost::scope_exit::aux::undeclared boost_local_auxXargs;
+ // Body.
+ inline boost_local_auxXresult_type19 body(const int& factor, double& sum, const double& num) const {
+ sum += factor * num;
+ }
+ public:
+ // This must always be the non-local functor even if optimizing because it cannot be a ref to this local functors because ctor cannot init the ref because it
+ // does not know the local function name.
+ casting_function_type add;
+ inline void init_recursion(casting_function_type& fctor) { add = fctor; } // cannot call from ctor to allow for opt
+ } add_fctor(boost_local_auxXargs.value);
+ BOOST_TYPEOF(add_fctor.add) add;
+ add_fctor.init_recursion(add);
+ add.set(&add_fctor, &add_fctor.call); // cannot set in ctor before init_recursion to allow for opt
+
+ std::vector<double> v(1e4 * 1e2);
+ std::fill(v.begin(), v.end(), 1.0);
+
+ for (size_t n = 0; n < 1e4; ++n) {
+ std::for_each(v.begin(), v.end(), add_fctor);
+// for (size_t i = 0; i < v.size(); ++i) add_lf(v[i]);
+ }
+
+ std::cout << sum << std::endl;
+ assert(sum == 1e4 * 1e4 * 1e2);
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/optim.03.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/optim.03.cpp 2011-04-13 11:36:37 EDT (Wed, 13 Apr 2011)
@@ -0,0 +1,164 @@
+
+#include <boost/local/function.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+#include <cassert>
+
+// This is a non-local functor so it can be passed as template parameter.
+// obj will be of local class type so it cannot be passed as template param (it is instead handled as a generic void pointer and the call function will cast it).
+template< typename R, typename A0, size_t defaults >
+class casting_function {
+ typedef R (*call_function)(void* obj, A0);
+public:
+ // public
+ explicit casting_function(void* obj = 0, call_function call = 0): obj_(obj), call_(call) {}
+ /* implicit for GCC */ casting_function(casting_function const& other): obj_(other.obj_), call_(other.call_) {}
+ // precondition: set
+ inline void operator()(A0 num) { call_(obj_, num); } // function pointer call cannot be inlined
+ // private
+ inline void set(void* obj = 0, call_function call = 0) { obj_ = obj; call_ = call; }
+private:
+ void* obj_;
+ call_function call_;
+};
+
+int main() {
+ double sum = 0.0;
+ int factor = 1;
+
+ void (*ERROR_missing_result_type_before_the_local_function_parameter_macro_id19)(); typedef void (*boost_local_auxXdeduce_result_tag19)( int ERROR_missing_result_type_before_the_local_function_parameter_macro_id19);
+ typedef BOOST_TYPEOF(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref( ERROR_missing_result_type_before_the_local_function_parameter_macro_id19, (boost_local_auxXdeduce_result_tag19)0))) boost_local_auxXdeduce_result_wrap19;
+ typedef boost_local_auxXdeduce_result_wrap19::type boost_local_auxXdeduce_result_capture19;
+ struct boost_local_auxXdeduce_result_params19 { typedef boost_local_auxXdeduce_result_capture19 function_ptr_type; };
+ typedef boost::remove_pointer< boost_local_auxXdeduce_result_params19::function_ptr_type >::type boost_local_auxXdeduce_result_function_type19;
+ typedef boost::function_traits< boost_local_auxXdeduce_result_function_type19>::result_type boost_local_auxXresult_type19;
+ typedef void (*boost_se_tag_0_19)(int & factor );
+ typedef void (*boost_se_tag_1_19)(int & sum );
+ typedef BOOST_TYPEOF(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref(& factor, (boost_se_tag_0_19)0))) boost_se_wrapped_t_0_19;
+ typedef boost_se_wrapped_t_0_19::type boost_se_capture_t_0_19;
+ typedef BOOST_TYPEOF(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref(& sum, (boost_se_tag_1_19)0))) boost_se_wrapped_t_1_19;
+ typedef boost_se_wrapped_t_1_19::type boost_se_capture_t_1_19;
+ struct boost_se_params_t_19 {
+ typedef boost_se_capture_t_0_19 boost_se_param_t_0_19;
+ typedef boost_se_capture_t_1_19 boost_se_param_t_1_19;
+ boost::scope_exit::aux::member< boost_se_param_t_0_19, boost_se_tag_0_19 > boost_se_param_0_19;
+ boost::scope_exit::aux::member< boost_se_param_t_1_19, boost_se_tag_1_19 > boost_se_param_1_19;
+ } boost_local_auxXparams19 = {
+#ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
+ {
+#endif
+ boost::scope_exit::aux::deref(& factor, (boost_se_tag_0_19)0)
+#ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
+ }
+#endif
+ ,
+#ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
+ {
+#endif
+ boost::scope_exit::aux::deref(& sum, (boost_se_tag_1_19)0)
+#ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
+ }
+#endif
+ };
+ 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_auxXparams19;
+
+ class boost_local_auxXfunctor19
+ : public ::boost::local::aux::abstract_function< boost_local_auxXresult_type19 ( const double& num ), 0 >
+ {
+ typedef boost_local_auxXresult_type19 (boost_local_auxXfunction_type) ( const double& num );
+ public:
+ explicit boost_local_auxXfunctor19(void* binding_data):
+ boost_local_auxXbinds(static_cast< boost_se_params_t_19*>(binding_data))
+ , factor(boost_local_auxXbinds->boost_se_param_0_19.value)
+ , sum(boost_local_auxXbinds-> boost_se_param_1_19.value)
+ {
+ boost_local_auxXinit_recursion();
+ }
+ boost_local_auxXresult_type19 operator()(::boost::call_traits< ::boost::function_traits<boost_local_auxXfunction_type>::arg1_type>::param_type arg1) {
+ return boost_local_auxXbody(arg1);
+ }
+ private:
+ typedef ::boost::local::function<boost_local_auxXfunction_type, 0 > boost_local_auxXfunctor_type;
+ typedef ::boost::add_const< boost_se_params_t_19:: boost_se_param_t_0_19 >::type & factorXboost_local_auxXtypeof_type ;
+ typedef boost_se_params_t_19:: boost_se_param_t_1_19 & sumXboost_local_auxXtypeof_type ;
+ boost_se_params_t_19* boost_local_auxXbinds;
+ boost::scope_exit::aux::undeclared boost_local_auxXargs;
+
+ ::boost::add_const< boost_se_params_t_19:: boost_se_param_t_0_19 >::type & factor;
+ boost_se_params_t_19:: boost_se_param_t_1_19 & sum;
+
+ boost_local_auxXresult_type19 boost_local_auxXbody(const double& num) const {
+ sum += factor * num;
+ }
+
+ private:
+ boost_local_auxXfunctor_type add;
+ private:
+ void boost_local_auxXinit_recursion() { add = *this; }
+ } add_bl(boost_local_auxXargs.value);
+ ::boost::local::function< boost_local_auxXresult_type19 ( const double& num ), 0 > add_f(add_bl);
+
+ class local_add
+// Cannot use virtual-base trick because it prevents optimizations also when passing the local functor as template param on C++03.
+// Use casting trick instead to allow for C++03 optimizations.
+// : public ::boost::local::aux::abstract_function<boost_local_auxXresult_type19 (const double& num), 0>
+ {
+ // Function and functor types.
+ typedef boost_local_auxXresult_type19 (boost_local_auxXfunction_type) (const double& num);
+ typedef casting_function< boost_local_auxXresult_type19, const double&, 0 > casting_function_type;
+ // For local-typeof.
+ typedef ::boost::add_const< boost_se_params_t_19:: boost_se_param_t_0_19 >::type & factorXboost_local_auxXtypeof_type ;
+ typedef boost_se_params_t_19:: boost_se_param_t_1_19 & sumXboost_local_auxXtypeof_type ;
+ public:
+ explicit local_add(void* binds):
+ bind1(static_cast< boost_se_params_t_19* >(binds)->boost_se_param_0_19.value)
+ , bind2(static_cast< boost_se_params_t_19* >(binds)->boost_se_param_1_19.value)
+ {}
+ // Leave here even if call is used so this class can be used as functor for C++03 optimizations.
+ inline boost_local_auxXresult_type19 operator()(const double& num) {
+ return body(
+ //boost_local_auxXbinds-> boost_se_param_0_19.value, boost_local_auxXbinds-> boost_se_param_1_19.value
+ bind1, bind2
+ , num);
+ }
+ // To pass local function as tparam on non C++03.
+ inline static boost_local_auxXresult_type19 call(void* obj, const double& num) {
+ return static_cast<local_add*>(obj)->operator()(num);
+ }
+ private:
+ // Use binds as single mem vars instead of accessing `boost_se_params_t_19* boost_local_auxXbinds` all the times improves performance.
+ // Always add ref because these data must just reference the actual data stored in the params struct declared outside this class (and passed to the ctor by
+ // ptr).
+ ::boost::add_const< boost_se_params_t_19:: boost_se_param_t_0_19 >::type & bind1;
+ boost_se_params_t_19:: boost_se_param_t_1_19 & bind2;
+ // For nesting.
+ boost::scope_exit::aux::undeclared boost_local_auxXargs;
+ // Body.
+ inline boost_local_auxXresult_type19 body(const int& factor, double& sum, const double& num) const {
+ sum += factor * num;
+ }
+ public:
+ // This must always be the non-local functor even if optimizing because it cannot be a ref to this local functors because ctor cannot init the ref because it
+ // does not know the local function name.
+ casting_function_type add;
+ inline void init_recursion(casting_function_type& fctor) { add = fctor; } // cannot call from ctor to allow for opt
+ } add_fctor(boost_local_auxXargs.value);
+ BOOST_TYPEOF(add_fctor.add) add;
+ add_fctor.init_recursion(add);
+ add.set(&add_fctor, &add_fctor.call); // cannot set in ctor before init_recursion to allow for opt
+
+ std::vector<double> v(1e4 * 1e2);
+ std::fill(v.begin(), v.end(), 1.0);
+
+ for (size_t n = 0; n < 1e4; ++n) {
+ std::for_each(v.begin(), v.end(), add_fctor);
+// for (size_t i = 0; i < v.size(); ++i) add_lf(v[i]);
+ }
+
+ std::cout << sum << std::endl;
+ assert(sum == 1e4 * 1e4 * 1e2);
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/optim.04.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/optim.04.cpp 2011-04-13 11:36:37 EDT (Wed, 13 Apr 2011)
@@ -0,0 +1,144 @@
+
+#include <boost/local/function.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+#include <cassert>
+
+// This is a non-local functor so it can be passed as template parameter.
+// obj will be of local class type so it cannot be passed as template param (it is instead handled as a generic void pointer and the call function will cast it).
+template< typename R, typename A0, size_t defaults >
+class casting_function {
+ typedef R (*call_type_0)(void*, A0);
+ typedef R (*call_type_1)(void*);
+public:
+ // public
+// inline explicit casting_function(): obj_(), call0_(), call1_() {}
+// inline /* implicit for GCC */ casting_function(const casting_function& other): obj_(other.obj_), call0_(other.call0_), call1_(other.call1_) {}
+ inline void init(void* obj, call_type_0 call0, call_type_1 call1) { obj_ = obj; call0_ = call0; call1_ = call1; }
+ inline void operator()(A0 num) { call0_(obj_, num); } // function pointer call cannot be inlined
+ inline void operator()() { call1_(obj_); }
+ // private
+private:
+ void* obj_;
+ call_type_0 call0_;
+ call_type_1 call1_;
+};
+
+int main() {
+ double sum = 0.0;
+ int factor = 1;
+
+ void (*ERROR_missing_result_type_before_the_local_function_parameter_macro_id19)(); typedef void (*boost_local_auxXdeduce_result_tag19)( int ERROR_missing_result_type_before_the_local_function_parameter_macro_id19);
+ typedef BOOST_TYPEOF(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref( ERROR_missing_result_type_before_the_local_function_parameter_macro_id19, (boost_local_auxXdeduce_result_tag19)0))) boost_local_auxXdeduce_result_wrap19;
+ typedef boost_local_auxXdeduce_result_wrap19::type boost_local_auxXdeduce_result_capture19;
+ struct boost_local_auxXdeduce_result_params19 { typedef boost_local_auxXdeduce_result_capture19 function_ptr_type; };
+ typedef boost::remove_pointer< boost_local_auxXdeduce_result_params19::function_ptr_type >::type boost_local_auxXdeduce_result_function_type19;
+ typedef boost::function_traits< boost_local_auxXdeduce_result_function_type19>::result_type boost_local_auxXresult_type19;
+ typedef void (*boost_se_tag_0_19)(int & factor );
+ typedef void (*boost_se_tag_1_19)(int & sum );
+ typedef BOOST_TYPEOF(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref(& factor, (boost_se_tag_0_19)0))) boost_se_wrapped_t_0_19;
+ typedef boost_se_wrapped_t_0_19::type boost_se_capture_t_0_19;
+ typedef BOOST_TYPEOF(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref(& sum, (boost_se_tag_1_19)0))) boost_se_wrapped_t_1_19;
+ typedef boost_se_wrapped_t_1_19::type boost_se_capture_t_1_19;
+ struct boost_se_params_t_19 {
+ typedef boost_se_capture_t_0_19 boost_se_param_t_0_19;
+ typedef boost_se_capture_t_1_19 boost_se_param_t_1_19;
+ boost::scope_exit::aux::member< boost_se_param_t_0_19, boost_se_tag_0_19 > boost_se_param_0_19;
+ boost::scope_exit::aux::member< boost_se_param_t_1_19, boost_se_tag_1_19 > boost_se_param_1_19;
+ } boost_local_auxXparams19 = {
+#ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
+ {
+#endif
+ boost::scope_exit::aux::deref(& factor, (boost_se_tag_0_19)0)
+#ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
+ }
+#endif
+ ,
+#ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
+ {
+#endif
+ boost::scope_exit::aux::deref(& sum, (boost_se_tag_1_19)0)
+#ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
+ }
+#endif
+ };
+ 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_auxXparams19;
+
+ class local_add
+// Cannot use virtual-base trick because it prevents optimizations also when passing the local functor as template param on C++03.
+// Use casting trick instead to allow for C++03 optimizations.
+// : public ::boost::local::aux::abstract_function<boost_local_auxXresult_type19 (const double& num), 0>
+ {
+ // Function and functor types.
+ typedef boost_local_auxXresult_type19 (boost_local_auxXfunction_type) (const double& num);
+ typedef casting_function< boost_local_auxXresult_type19, const double&, 0 > casting_function_type;
+ // For local-typeof.
+ typedef ::boost::add_const< boost_se_params_t_19:: boost_se_param_t_0_19 >::type & factorXboost_local_auxXtypeof_type ;
+ typedef boost_se_params_t_19:: boost_se_param_t_1_19 & sumXboost_local_auxXtypeof_type ;
+ public:
+ inline explicit local_add(void* binds):
+ bind1(static_cast< boost_se_params_t_19* >(binds)->boost_se_param_0_19.value)
+ , bind2(static_cast< boost_se_params_t_19* >(binds)->boost_se_param_1_19.value)
+ {}
+ // Leave here even if call is used so this class can be used as functor for C++03 optimizations.
+ inline boost_local_auxXresult_type19 operator()(const double& num) {
+ return body(bind1, bind2, num);
+ }
+ inline boost_local_auxXresult_type19 operator()() {
+ return body(bind1, bind2);
+ }
+ // To pass local function as tparam on non C++03.
+ inline static boost_local_auxXresult_type19 call0(void* obj, const double& num) {
+ return static_cast<local_add*>(obj)->operator()(num);
+ }
+ inline static boost_local_auxXresult_type19 call1(void* obj) {
+ return static_cast<local_add*>(obj)->operator()();
+ }
+ inline static void init_functor(void* object, casting_function_type& fctor) {
+ fctor.init(object, &call0, &call1); // here knows default_counts
+ }
+ private:
+ // Use binds as single mem vars instead of accessing `boost_se_params_t_19* boost_local_auxXbinds` all the times improves performance.
+ // Always add ref because these data must just reference the actual data stored in the params struct declared outside this class (and passed to the ctor by
+ // ptr).
+ ::boost::add_const< boost_se_params_t_19:: boost_se_param_t_0_19 >::type & bind1;
+ boost_se_params_t_19:: boost_se_param_t_1_19 & bind2;
+ // For nesting.
+ boost::scope_exit::aux::undeclared boost_local_auxXargs;
+ // Body.
+ inline boost_local_auxXresult_type19 body(
+ ::boost::add_const< boost_se_params_t_19:: boost_se_param_t_0_19 >::type& factor
+ , boost_se_params_t_19:: boost_se_param_t_1_19& sum
+ , const double& num = 0.0) const {
+ sum += factor * num;
+ }
+ public:
+ // This must always be the non-local functor even if optimizing because it cannot be a ref to this local functors because ctor cannot init the ref because it
+ // does not know the local function name.
+ casting_function_type add;
+ inline void init_recursion(casting_function_type& fctor) { add = fctor; } // cannot call from ctor to allow for opt
+ } add_fctor(boost_local_auxXargs.value);
+ BOOST_TYPEOF(add_fctor.add) add;
+ add_fctor.init_recursion(add);
+ add_fctor.init_functor(&add_fctor, add);
+
+// add_fctor(1.23);
+// add_fctor();
+// add(3.21);
+// add();
+
+ std::vector<double> v(1e4 * 1e2);
+ std::fill(v.begin(), v.end(), 1.0);
+
+ for (size_t n = 0; n < 1e4; ++n) {
+ std::for_each(v.begin(), v.end(), add_fctor);
+// for (size_t i = 0; i < v.size(); ++i) add_lf(v[i]);
+ }
+
+ std::cout << sum << std::endl;
+ assert(sum == 1e4 * 1e4 * 1e2);
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/optim.05.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/optim.05.cpp 2011-04-13 11:36:37 EDT (Wed, 13 Apr 2011)
@@ -0,0 +1,142 @@
+
+#include <boost/local/function.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+#include <cassert>
+
+// This is a non-local functor so it can be passed as template parameter.
+// obj will be of local class type so it cannot be passed as template param (it is instead handled as a generic void pointer and the call function will cast it).
+template< typename R, typename A0, size_t defaults >
+class casting_function {
+ typedef R (*call_type_0)(void*, A0);
+ typedef R (*call_type_1)(void*);
+public:
+ // public
+// inline explicit casting_function(): obj_(), call0_(), call1_() {}
+// inline /* implicit for GCC */ casting_function(const casting_function& other): obj_(other.obj_), call0_(other.call0_), call1_(other.call1_) {}
+ inline void init(void* obj, call_type_0 call0, call_type_1 call1) { obj_ = obj; call0_ = call0; call1_ = call1; }
+ inline void operator()(A0 num) { call0_(obj_, num); } // function pointer call cannot be inlined
+ inline void operator()() { call1_(obj_); }
+ // private
+private:
+ void* obj_;
+ call_type_0 call0_;
+ call_type_1 call1_;
+};
+
+template< typename R, typename A0, size_t defaults >
+class casting_function0 {
+ typedef R (*call_type_0)(void*, A0);
+public:
+ inline void boost_local_auxXinit_call(void* obj, call_type_0 call0) { obj_ = obj; call0_ = call0; }
+ inline void operator()(A0 arg0) { call0_(obj_, arg0); }
+private:
+ void* obj_;
+ call_type_0 call0_;
+};
+
+int main() {
+ double sum = 0.0;
+ int factor = 1;
+
+ void (*ERROR_missing_result_type_before_the_local_function_parameter_macro_id19)(); typedef void (*boost_local_auxXdeduce_result_tag19)( int ERROR_missing_result_type_before_the_local_function_parameter_macro_id19);
+ typedef BOOST_TYPEOF(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref( ERROR_missing_result_type_before_the_local_function_parameter_macro_id19, (boost_local_auxXdeduce_result_tag19)0))) boost_local_auxXdeduce_result_wrap19;
+ typedef boost_local_auxXdeduce_result_wrap19::type boost_local_auxXdeduce_result_capture19;
+ struct boost_local_auxXdeduce_result_params19 { typedef boost_local_auxXdeduce_result_capture19 function_ptr_type; };
+ typedef boost::remove_pointer< boost_local_auxXdeduce_result_params19::function_ptr_type >::type boost_local_auxXdeduce_result_function_type19;
+ typedef boost::function_traits< boost_local_auxXdeduce_result_function_type19>::result_type boost_local_auxXresult_type19;
+ typedef void (*boost_se_tag_0_19)(int & factor );
+ typedef void (*boost_se_tag_1_19)(int & sum );
+ typedef BOOST_TYPEOF(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref(& factor, (boost_se_tag_0_19)0))) boost_se_wrapped_t_0_19;
+ typedef boost_se_wrapped_t_0_19::type boost_se_capture_t_0_19;
+ typedef BOOST_TYPEOF(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref(& sum, (boost_se_tag_1_19)0))) boost_se_wrapped_t_1_19;
+ typedef boost_se_wrapped_t_1_19::type boost_se_capture_t_1_19;
+ struct boost_se_params_t_19 {
+ typedef boost_se_capture_t_0_19 boost_se_param_t_0_19;
+ typedef boost_se_capture_t_1_19 boost_se_param_t_1_19;
+ boost::scope_exit::aux::member< boost_se_param_t_0_19, boost_se_tag_0_19 > boost_se_param_0_19;
+ boost::scope_exit::aux::member< boost_se_param_t_1_19, boost_se_tag_1_19 > boost_se_param_1_19;
+ } boost_local_auxXparams19 = {
+#ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
+ {
+#endif
+ boost::scope_exit::aux::deref(& factor, (boost_se_tag_0_19)0)
+#ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
+ }
+#endif
+ ,
+#ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
+ {
+#endif
+ boost::scope_exit::aux::deref(& sum, (boost_se_tag_1_19)0)
+#ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
+ }
+#endif
+ };
+ 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_auxXparams19;
+
+ class boost_local_auxXfunctor19 {
+ typedef boost_local_auxXresult_type19 (boost_local_auxXfunction_type) (const double& num);
+// typedef ::boost::local::function< boost_local_auxXfunction_type, 0 > boost_local_auxXfunctor_type;
+ typedef casting_function0< boost_local_auxXresult_type19, const double&, 0 > boost_local_auxXfunctor_type;
+
+ typedef ::boost::add_const< boost_se_params_t_19:: boost_se_param_t_0_19 >::type & factorXboost_local_auxXtypeof_type ;
+ typedef boost_se_params_t_19:: boost_se_param_t_1_19 & sumXboost_local_auxXtypeof_type ;
+
+ public:
+ inline explicit boost_local_auxXfunctor19(void* bindings):
+ boost_local_auxXbind0( static_cast< boost_se_params_t_19* >(bindings)->boost_se_param_0_19.value )
+ , boost_local_auxXbind1( static_cast< boost_se_params_t_19* >(bindings)->boost_se_param_1_19.value )
+ {}
+
+ inline boost_local_auxXresult_type19 operator()(
+ ::boost::call_traits< ::boost::function_traits< boost_local_auxXfunction_type >::arg1_type >::param_type arg1) {
+ return boost_local_auxXbody(boost_local_auxXbind0, boost_local_auxXbind1, arg1);
+ }
+ inline static boost_local_auxXresult_type19 boost_local_auxXcall0(void* obj, const double& num) {
+ return static_cast<boost_local_auxXfunctor19*>(obj)->operator()(num);
+ }
+ inline static void boost_local_auxXinit_call(void* object, boost_local_auxXfunctor_type& functor) {
+ functor.boost_local_auxXinit_call(object, &boost_local_auxXcall0 );
+ }
+ private:
+ ::boost::add_const< boost_se_params_t_19:: boost_se_param_t_0_19 >::type & boost_local_auxXbind0;
+ boost_se_params_t_19:: boost_se_param_t_1_19 & boost_local_auxXbind1;
+
+ boost::scope_exit::aux::undeclared boost_local_auxXargs;
+
+ inline boost_local_auxXresult_type19 boost_local_auxXbody(
+ ::boost::add_const< boost_se_params_t_19:: boost_se_param_t_0_19 >::type& factor
+ , boost_se_params_t_19:: boost_se_param_t_1_19& sum
+ , const double& num
+ ) const {
+ sum += factor * num;
+ }
+ public:
+ boost_local_auxXfunctor_type add;
+ inline void boost_local_auxXinit_recursion(boost_local_auxXfunctor_type& functor) { add = functor; }
+ } add(boost_local_auxXargs.value);
+ BOOST_TYPEOF(add.add) boost_local_auxXadd;
+ add.boost_local_auxXinit_recursion(boost_local_auxXadd);
+ add.boost_local_auxXinit_call(&add, boost_local_auxXadd);
+
+// add_fctor(1.23);
+// add_fctor();
+// add(3.21);
+// add();
+
+ std::vector<double> v(1e4 * 1e2);
+ std::fill(v.begin(), v.end(), 1.0);
+
+ for (size_t n = 0; n < 1e4; ++n) {
+ std::for_each(v.begin(), v.end(), add);
+// for (size_t i = 0; i < v.size(); ++i) add_lf(v[i]);
+ }
+
+ std::cout << sum << std::endl;
+ assert(sum == 1e4 * 1e4 * 1e2);
+ return 0;
+}
+

Added: sandbox/local/libs/local/example/optim.06.cpp
==============================================================================
--- (empty file)
+++ sandbox/local/libs/local/example/optim.06.cpp 2011-04-13 11:36:37 EDT (Wed, 13 Apr 2011)
@@ -0,0 +1,159 @@
+
+#include <boost/local/function.hpp>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+#include <cassert>
+
+template< typename F, size_t defaults = 0 >
+struct casting_function {};
+
+/*
+template< typename R, typename A0 >
+class casting_function< R (A0), 0 > {
+ typedef R (*call_type_0)(void*, A0);
+public:
+ inline void init(void* obj, call_type_0 call0) { obj_ = obj; call0_ = call0; }
+ inline void operator()(A0 num) { call0_(obj_, num); }
+private:
+ void* obj_;
+ call_type_0 call0_;
+ void* call1_;
+ void* call2_;
+};
+*/
+
+template< typename R, typename A0 >
+class casting_function< R (A0), 0 > {
+ typedef void* object_ptr;
+ typedef R (*call_ptr0)(object_ptr , typename ::boost::call_traits<A0 >::param_type);
+public:
+ inline void init(object_ptr object, call_ptr0 call0) {
+ object_ = object;
+ call0_ = call0;
+ }
+ inline R operator()( typename ::boost::call_traits<A0 >::param_type a0) const { return call0_(object_ , a0); }
+private:
+ object_ptr object_;
+ call_ptr0 call0_;
+ void* call1_;
+ void* call2_;
+};
+
+int main() {
+ double sum = 0.0;
+ int factor = 1;
+
+ void (*ERROR_missing_result_type_before_the_local_function_parameter_macro_id19)(); typedef void (*boost_local_auxXdeduce_result_tag19)( int ERROR_missing_result_type_before_the_local_function_parameter_macro_id19);
+ typedef BOOST_TYPEOF(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref( ERROR_missing_result_type_before_the_local_function_parameter_macro_id19, (boost_local_auxXdeduce_result_tag19)0))) boost_local_auxXdeduce_result_wrap19;
+ typedef boost_local_auxXdeduce_result_wrap19::type boost_local_auxXdeduce_result_capture19;
+ struct boost_local_auxXdeduce_result_params19 { typedef boost_local_auxXdeduce_result_capture19 function_ptr_type; };
+ typedef boost::remove_pointer< boost_local_auxXdeduce_result_params19::function_ptr_type >::type boost_local_auxXdeduce_result_function_type19;
+ typedef boost::function_traits< boost_local_auxXdeduce_result_function_type19>::result_type boost_local_auxXresult_type19;
+ typedef void (*boost_se_tag_0_19)(int & factor );
+ typedef void (*boost_se_tag_1_19)(int & sum );
+ typedef BOOST_TYPEOF(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref(& factor, (boost_se_tag_0_19)0))) boost_se_wrapped_t_0_19;
+ typedef boost_se_wrapped_t_0_19::type boost_se_capture_t_0_19;
+ typedef BOOST_TYPEOF(boost::scope_exit::aux::wrap( boost::scope_exit::aux::deref(& sum, (boost_se_tag_1_19)0))) boost_se_wrapped_t_1_19;
+ typedef boost_se_wrapped_t_1_19::type boost_se_capture_t_1_19;
+ struct boost_se_params_t_19 {
+ typedef boost_se_capture_t_0_19 boost_se_param_t_0_19;
+ typedef boost_se_capture_t_1_19 boost_se_param_t_1_19;
+ boost::scope_exit::aux::member< boost_se_param_t_0_19, boost_se_tag_0_19 > boost_se_param_0_19;
+ boost::scope_exit::aux::member< boost_se_param_t_1_19, boost_se_tag_1_19 > boost_se_param_1_19;
+ } boost_local_auxXparams19 = {
+#ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
+ {
+#endif
+ boost::scope_exit::aux::deref(& factor, (boost_se_tag_0_19)0)
+#ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
+ }
+#endif
+ ,
+#ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
+ {
+#endif
+ boost::scope_exit::aux::deref(& sum, (boost_se_tag_1_19)0)
+#ifdef BOOST_SCOPE_EXIT_AUX_TPL_WORKAROUND
+ }
+#endif
+ };
+ 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_auxXparams19;
+
+ class local_add
+// Cannot use virtual-base trick because it prevents optimizations also when passing the local functor as template param on C++03.
+// Use casting trick instead to allow for C++03 optimizations.
+// : public ::boost::local::aux::abstract_function<boost_local_auxXresult_type19 (const double& num), 0>
+ {
+ // Function and functor types.
+ typedef boost_local_auxXresult_type19 (boost_local_auxXfunction_type) (const double& num);
+ typedef casting_function< boost_local_auxXfunction_type, 0 > casting_function_type;
+ // For local-typeof.
+ typedef ::boost::add_const< boost_se_params_t_19:: boost_se_param_t_0_19 >::type & factorXboost_local_auxXtypeof_type ;
+ typedef boost_se_params_t_19:: boost_se_param_t_1_19 & sumXboost_local_auxXtypeof_type ;
+ public:
+ inline explicit local_add(void* binds):
+ bind1(static_cast< boost_se_params_t_19* >(binds)->boost_se_param_0_19.value)
+ , bind2(static_cast< boost_se_params_t_19* >(binds)->boost_se_param_1_19.value)
+ {}
+ // Leave here even if call is used so this class can be used as functor for C++03 optimizations.
+ inline boost_local_auxXresult_type19 operator()(::boost::call_traits< ::boost::function_traits< boost_local_auxXfunction_type>::arg1_type>::param_type arg1) {
+ return body(bind1, bind2, arg1);
+ }
+ inline boost_local_auxXresult_type19 operator()() {
+ return body(bind1, bind2);
+ }
+ // To pass local function as tparam on non C++03.
+ inline static boost_local_auxXresult_type19 call0(void* obj, const double& num) {
+ return static_cast<local_add*>(obj)->operator()(num);
+ }
+ inline static boost_local_auxXresult_type19 call1(void* obj) {
+ return static_cast<local_add*>(obj)->operator()();
+ }
+ inline static void init_functor(void* object, casting_function_type& fctor) {
+ fctor.init(object, &call0); // here knows default_counts
+ }
+ private:
+ // Use binds as single mem vars instead of accessing `boost_se_params_t_19* boost_local_auxXbinds` all the times improves performance.
+ // Always add ref because these data must just reference the actual data stored in the params struct declared outside this class (and passed to the ctor by
+ // ptr).
+ ::boost::add_const< boost_se_params_t_19:: boost_se_param_t_0_19 >::type & bind1;
+ boost_se_params_t_19:: boost_se_param_t_1_19 & bind2;
+ // For nesting.
+ boost::scope_exit::aux::undeclared boost_local_auxXargs;
+ // Body.
+ inline boost_local_auxXresult_type19 body(
+ ::boost::add_const< boost_se_params_t_19:: boost_se_param_t_0_19 >::type& factor
+ , boost_se_params_t_19:: boost_se_param_t_1_19& sum
+ , const double& num = 0.0) const {
+ sum += factor * num;
+ }
+ public:
+ // This must always be the non-local functor even if optimizing because it cannot be a ref to this local functors because ctor cannot init the ref because it
+ // does not know the local function name.
+ casting_function_type add;
+ inline void init_recursion(casting_function_type& fctor) { add = fctor; } // cannot call from ctor to allow for opt
+ } add_fctor(boost_local_auxXargs.value);
+ BOOST_TYPEOF(add_fctor.add) add;
+ add_fctor.init_recursion(add);
+ add_fctor.init_functor(&add_fctor, add);
+
+// add_fctor(1.23);
+// add_fctor();
+// add(3.21);
+// add();
+
+ std::vector<double> v(1e4 * 1e2);
+ std::fill(v.begin(), v.end(), 1.0);
+
+ for (size_t n = 0; n < 1e4; ++n) {
+ std::for_each(v.begin(), v.end(), add_fctor);
+// for (size_t i = 0; i < v.size(); ++i) add_lf(v[i]);
+ }
+
+ std::cout << sum << std::endl;
+ assert(sum == 1e4 * 1e4 * 1e2);
+ 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