$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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;
+}
+