Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r71224 - in sandbox/local: boost/local/aux_ boost/local/aux_/function_macros boost/local/aux_/function_macros/code_ libs/local/example
From: lorcaminiti_at_[hidden]
Date: 2011-04-13 11:34:48


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

Log:
Improved run-time (for MSVC).
Removed:
   sandbox/local/boost/local/aux_/abstract_function.hpp
Text files modified:
   sandbox/local/boost/local/aux_/function.hpp | 130 ++++++++++---
   sandbox/local/boost/local/aux_/function_macros/code_/functor.hpp | 367 ++++++++++++++++++++++++++++-----------
   sandbox/local/boost/local/aux_/function_macros/name.hpp | 95 +++++----
   sandbox/local/boost/local/aux_/symbol.hpp | 3
   sandbox/local/libs/local/example/benchmark_boost_local.cpp | 6
   5 files changed, 423 insertions(+), 178 deletions(-)

Deleted: sandbox/local/boost/local/aux_/abstract_function.hpp
==============================================================================
--- sandbox/local/boost/local/aux_/abstract_function.hpp 2011-04-13 11:34:46 EDT (Wed, 13 Apr 2011)
+++ (empty file)
@@ -1,88 +0,0 @@
-
-// 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).
-
-#if !BOOST_PP_IS_ITERATING
-# ifndef BOOST_LOCAL_AUX_ABSTRACT_FUNCTION_HPP_
-# define BOOST_LOCAL_AUX_ABSTRACT_FUNCTION_HPP_
-
-# include "file.hpp"
-# include "../config.hpp"
-# include <boost/call_traits.hpp>
-# include <boost/preprocessor/iteration/iterate.hpp>
-# include <boost/preprocessor/repetition/repeat.hpp>
-# include <boost/preprocessor/repetition/enum.hpp>
-# include <boost/preprocessor/punctuation/comma_if.hpp>
-# include <boost/preprocessor/arithmetic/sub.hpp>
-# include <boost/preprocessor/arithmetic/inc.hpp>
-# include <boost/preprocessor/cat.hpp>
-
-#define BOOST_LOCAL_AUX_arg_type(z, arg_n, unused) \
- BOOST_PP_CAT(A, arg_n)
-
-#define BOOST_LOCAL_AUX_arg_typename(z, arg_n, unused) \
- typename BOOST_LOCAL_AUX_arg_type(z, arg_n, unused)
-
-#define BOOST_LOCAL_AUX_param_type(z, arg_n, unused) \
- typename ::boost::call_traits<BOOST_LOCAL_AUX_arg_type(z, arg_n, unused) \
- >::param_type
-
-#define BOOST_LOCAL_AUX_abstract_operator_call(z, defaults_n, arity) \
- virtual R operator()(BOOST_PP_ENUM_ ## z(BOOST_PP_SUB(arity, defaults_n), \
- BOOST_LOCAL_AUX_param_type, ~)) = 0;
-
-#define BOOST_LOCAL_AUX_template_name(defaults_count) \
- BOOST_PP_CAT(BOOST_PP_CAT(functor_defaults, defaults_count), _base)
-
-namespace boost { namespace local { namespace aux {
-
-template<typename F, unsigned int defaults_count = 0> // Defaults count is opt.
-struct abstract_function {}; // Empty so never used directly.
-
-// Iteration within the namespace.
-# define BOOST_PP_ITERATION_PARAMS_1 \
- (3, (0, BOOST_LOCAL_CONFIG_FUNCTION_ARITY_MAX, \
- BOOST_LOCAL_AUX_FILE_ABSTRACT_FUNCTION_HPP))
-# include BOOST_PP_ITERATE() // Iterate over arity.
-
-}}} // namespace boost::local::aux
-
-# undef BOOST_LOCAL_AUX_arg_type
-# undef BOOST_LOCAL_AUX_arg_typename
-# undef BOOST_LOCAL_AUX_param_type
-# undef BOOST_LOCAL_AUX_abstract_operator_call
-# undef BOOST_LOCAL_AUX_template_name
-
-# endif // #include guard
-
-#elif BOOST_PP_ITERATION_DEPTH() == 1
-# define BOOST_LOCAL_AUX_arity BOOST_PP_FRAME_ITERATION(1)
-
-# define BOOST_PP_ITERATION_PARAMS_2 \
- (3, (0, BOOST_LOCAL_AUX_arity, \
- BOOST_LOCAL_AUX_FILE_ABSTRACT_FUNCTION_HPP))
-# include BOOST_PP_ITERATE() // Iterate over default params count.
-# undef BOOST_LOCAL_AUX_arity
-
-#elif BOOST_PP_ITERATION_DEPTH() == 2
-# define BOOST_LOCAL_AUX_defaults_count BOOST_PP_FRAME_ITERATION(2)
-
-template<typename R
- BOOST_PP_COMMA_IF(BOOST_LOCAL_AUX_arity)
- BOOST_PP_ENUM(BOOST_LOCAL_AUX_arity, BOOST_LOCAL_AUX_arg_typename, ~)
->
-struct abstract_function<
- R (BOOST_PP_ENUM(BOOST_LOCAL_AUX_arity, BOOST_LOCAL_AUX_arg_type, ~))
- , BOOST_LOCAL_AUX_defaults_count
-> {
- // INC for no dflt.
- BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_LOCAL_AUX_defaults_count),
- BOOST_LOCAL_AUX_abstract_operator_call, BOOST_LOCAL_AUX_arity)
-};
-
-# undef BOOST_LOCAL_AUX_defaults_count
-
-#endif // iteration
-

Modified: sandbox/local/boost/local/aux_/function.hpp
==============================================================================
--- sandbox/local/boost/local/aux_/function.hpp (original)
+++ sandbox/local/boost/local/aux_/function.hpp 2011-04-13 11:34:46 EDT (Wed, 13 Apr 2011)
@@ -8,7 +8,6 @@
 # ifndef BOOST_LOCAL_AUX_FUNCTION_HPP_
 # define BOOST_LOCAL_AUX_FUNCTION_HPP_
 
-# include "abstract_function.hpp"
 # include "file.hpp"
 # include "../config.hpp"
 # include <boost/call_traits.hpp>
@@ -19,28 +18,66 @@
 # include <boost/preprocessor/arithmetic/sub.hpp>
 # include <boost/preprocessor/arithmetic/inc.hpp>
 # include <boost/preprocessor/cat.hpp>
-# include <cassert>
 
 #define BOOST_LOCAL_AUX_arg_type(z, arg_n, unused) \
     BOOST_PP_CAT(A, arg_n)
 
+#define BOOST_LOCAL_AUX_arg_param_type(z, arg_n, unused) \
+ typename ::boost::call_traits<BOOST_LOCAL_AUX_arg_type(z, arg_n, unused) \
+ >::param_type
+
 #define BOOST_LOCAL_AUX_arg_name(z, arg_n, unused) \
     BOOST_PP_CAT(a, arg_n)
 
 #define BOOST_LOCAL_AUX_arg(z, arg_n, unused) \
- typename ::boost::call_traits<BOOST_LOCAL_AUX_arg_type(z, arg_n, unused) \
- >::param_type \
+ BOOST_LOCAL_AUX_arg_param_type(z, arg_n, unused) \
     BOOST_LOCAL_AUX_arg_name(z, arg_n, unused)
 
-#define BOOST_LOCAL_AUX_arg_typename(z, arg_n, unused) \
+#define BOOST_LOCAL_AUX_arg_tparam(z, arg_n, unused) \
     typename BOOST_LOCAL_AUX_arg_type(z, arg_n, unused)
+
+#define BOOST_LOCAL_AUX_call_ptr(z, n, unused) \
+ BOOST_PP_CAT(call_ptr, n)
+
+#define BOOST_LOCAL_AUX_call_name(z, n, unused) \
+ BOOST_PP_CAT(call, n)
+
+#define BOOST_LOCAL_AUX_call_member(z, n, unused) \
+ BOOST_PP_CAT(BOOST_LOCAL_AUX_call_name(z, n, unused), _)
+
+#define BOOST_LOCAL_AUX_call_typedef(z, n, arity) \
+ typedef R (*BOOST_LOCAL_AUX_call_ptr(z, n, ~))(object_ptr \
+ BOOST_PP_COMMA_IF(BOOST_PP_SUB(arity, n)) \
+ BOOST_PP_ENUM_ ## z(BOOST_PP_SUB(arity, n), \
+ BOOST_LOCAL_AUX_arg_param_type, ~));
+
+#define BOOST_LOCAL_AUX_call_param(z, n, unused) \
+ BOOST_LOCAL_AUX_call_ptr(z, n, unused) \
+ BOOST_LOCAL_AUX_call_name(z, n, unused)
+
+#define BOOST_LOCAL_AUX_call_decl(z, n, unused) \
+ BOOST_LOCAL_AUX_call_ptr(z, n, unused) \
+ BOOST_LOCAL_AUX_call_member(z, n, unused);
+
+#define BOOST_LOCAL_AUX_call_init(z, n, unused) \
+ BOOST_LOCAL_AUX_call_member(z, n, unused) = \
+ BOOST_LOCAL_AUX_call_name(z, n, unuzed);
                 
-#define BOOST_LOCAL_AUX_concrete_operator_call(z, defaults_n, arity) \
- R operator()(BOOST_PP_ENUM_ ## z(BOOST_PP_SUB(arity, defaults_n), \
+#define BOOST_LOCAL_AUX_operator_call(z, defaults_n, arity) \
+ /* precondition: object_ && call_function_ */ \
+ inline R operator()(BOOST_PP_ENUM_ ## z(BOOST_PP_SUB(arity, defaults_n), \
                 BOOST_LOCAL_AUX_arg, ~)) const { \
- assert(ptr_); \
- return (*ptr_)(BOOST_PP_ENUM_ ## z(BOOST_PP_SUB(arity, defaults_n), \
- BOOST_LOCAL_AUX_arg_name, ~)); \
+ /* run-time: do not assert preconditions here for efficiency */ \
+ /* run-time: this function call is done via a function pointer */ \
+ /* so unfortunately does not allow for compiler inlining */ \
+ /* optimizations (an alternative using virtual function was also */ \
+ /* investigated but also virtual functions cannot be optimized */ \
+ /* plus they require virtual table lookups to the alternative */ \
+ /* performed worst) */ \
+ return BOOST_LOCAL_AUX_call_member(z, defaults_n, ~)(object_ \
+ BOOST_PP_COMMA_IF(BOOST_PP_SUB(arity, defaults_n)) \
+ BOOST_PP_ENUM_ ## z(BOOST_PP_SUB(arity, defaults_n), \
+ BOOST_LOCAL_AUX_arg_name, ~)); \
     }
 
 // Iteration within the namespace.
@@ -49,11 +86,19 @@
                 BOOST_LOCAL_AUX_FILE_FUNCTION_HPP))
 # include BOOST_PP_ITERATE() // Iterate over arity.
 
-# undef BOOST_LOCAL_AUX_arg_type
-# undef BOOST_LOCAL_AUX_arg_name
-# undef BOOST_LOCAL_AUX_arg
-# undef BOOST_LOCAL_AUX_rg_typename
-# undef BOOST_LOCAL_AUX_concrete_operator_call
+#undef BOOST_LOCAL_AUX_arg_type
+#undef BOOST_LOCAL_AUX_arg_param_type
+#undef BOOST_LOCAL_AUX_arg_name
+#undef BOOST_LOCAL_AUX_arg
+#undef BOOST_LOCAL_AUX_arg_tparam
+#undef BOOST_LOCAL_AUX_call_ptr
+#undef BOOST_LOCAL_AUX_call_name
+#undef BOOST_LOCAL_AUX_call_member
+#undef BOOST_LOCAL_AUX_call_typedef
+#undef BOOST_LOCAL_AUX_call_param
+#undef BOOST_LOCAL_AUX_call_decl
+#undef BOOST_LOCAL_AUX_call_init
+#undef BOOST_LOCAL_AUX_operator_call
 
 # endif // #include guard
 
@@ -74,35 +119,58 @@
 
 template<typename R
     BOOST_PP_COMMA_IF(BOOST_LOCAL_AUX_arity)
- BOOST_PP_ENUM(BOOST_LOCAL_AUX_arity, BOOST_LOCAL_AUX_arg_typename, ~)
+ BOOST_PP_ENUM(BOOST_LOCAL_AUX_arity, BOOST_LOCAL_AUX_arg_tparam, ~)
>
 class function<
       R (BOOST_PP_ENUM(BOOST_LOCAL_AUX_arity, BOOST_LOCAL_AUX_arg_type, ~))
     , BOOST_LOCAL_AUX_defaults
> {
- typedef aux::abstract_function<
- R (BOOST_PP_ENUM(BOOST_LOCAL_AUX_arity, BOOST_LOCAL_AUX_arg_type, ~))
- , BOOST_LOCAL_AUX_defaults
- > abstract_function_type;
-
+ // The object type will actually be a local class which cannot be passed as
+ // a template parameter so a generic `void*` pointer is used to hold the
+ // object (this pointer will then be cased by the call-function implemented
+ // by the local class itself). This is the trick used to pass a local
+ // function as a template parameter. This trick uses function pointers for
+ // the call-functions and function pointers cannot always be optimized by
+ // the compiler (they cannot be inlined) thus this trick increased run-time
+ // (another trick using virtual functions for the local class was also
+ // investigated but also virtual functions cannot be inlined plus they
+ // require virtual tables lookups so the virtual functions trick measured
+ // worst run-time performance than the function pointer trick).
+ typedef void* object_ptr;
+ BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_LOCAL_AUX_defaults), // INC for no dflt.
+ BOOST_LOCAL_AUX_call_typedef, BOOST_LOCAL_AUX_arity)
 public:
- /* implicit */ function(): ptr_() {} // Default constructor.
-
- /* implicit */ function(abstract_function_type& ref): ptr_(&ref) {}
-
- function& operator=(abstract_function_type& ref) {
- ptr_ = &ref;
- return *this;
+ // run-time: use compiler-generated default constructor, copy constructor,
+ // and copy operator (this class only has pointers as member variables and
+ // they only need to be copied shallowly so the compiler-generator
+ // operations work well) to allow for compiler optimization
+
+ // Cannot be private but it should never be used by programmers directly
+ // so used internal symbol.
+ inline void BOOST_LOCAL_AUX_SYMBOL_INIT_CALL_FUNCTION_NAME(
+ object_ptr object,
+ BOOST_PP_ENUM(BOOST_PP_INC(BOOST_LOCAL_AUX_defaults), // INC no dflt.
+ BOOST_LOCAL_AUX_call_param, ~)
+ ) {
+ object_ = object;
+ BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_LOCAL_AUX_defaults),
+ BOOST_LOCAL_AUX_call_init, ~)
     }
-
+
     // Result operator(Arg1, ..., ArgN-1, ArgN) // iff defaults >= 0
     // Result operator(Arg1, ..., ArgN-1) // iff defaults >= 1
     // ... // etc
     BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_LOCAL_AUX_defaults), // INC for no dflt.
- BOOST_LOCAL_AUX_concrete_operator_call, BOOST_LOCAL_AUX_arity)
+ BOOST_LOCAL_AUX_operator_call, BOOST_LOCAL_AUX_arity)
 
 private:
- abstract_function_type* ptr_;
+ object_ptr object_;
+ BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_LOCAL_AUX_defaults), // INC for no dflt.
+ BOOST_LOCAL_AUX_call_decl, ~)
+
+ // run-time: this unused void* member variable allows for compiler
+ // optimizations (at least on MSVC it reduces invocation time of about 50%)
+ void* unused_;
 };
 
 }} // namespace boost::local

Modified: sandbox/local/boost/local/aux_/function_macros/code_/functor.hpp
==============================================================================
--- sandbox/local/boost/local/aux_/function_macros/code_/functor.hpp (original)
+++ sandbox/local/boost/local/aux_/function_macros/code_/functor.hpp 2011-04-13 11:34:46 EDT (Wed, 13 Apr 2011)
@@ -8,7 +8,6 @@
 #define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_HPP_
 
 #include "bind_this.hpp"
-#include "../../abstract_function.hpp"
 #include "../../symbol.hpp"
 #include "../../preprocessor/sign/params_unbind.hpp"
 #include "../../preprocessor/sign/params_const_bind.hpp"
@@ -86,6 +85,16 @@
 
 // Bound parameters.
 
+#define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_BIND_PARAM_ \
+ bindings /* constructor parameter `void*` bindings pointer */
+
+#define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_VAR_(i) \
+ /* named `bind0`, `bind1`, ... */ \
+ BOOST_LOCAL_AUX_INTERNAL_SYMBOL(BOOST_PP_CAT(bind, i))
+
+#define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_BIND_MEMBER_THIS_ \
+ BOOST_LOCAL_AUX_INTERNAL_SYMBOL(bind_this)
+
 #define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_BIND_TYPE_( \
         id_typename_offset, i, var) \
     BOOST_SCOPE_EXIT_AUX_PARAMS_T( \
@@ -95,13 +104,10 @@
             BOOST_PP_ADD(i, BOOST_PP_TUPLE_ELEM(3, 2, id_typename_offset)),\
             var)
 
-#define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_BIND_VALUE_( \
- id_offset, i, var) \
- BOOST_LOCAL_AUX_SYMBOL_BINDS_VARIABLE_NAME-> \
- BOOST_SCOPE_EXIT_AUX_PARAM( \
- BOOST_PP_TUPLE_ELEM(2, 0, id_offset), \
- BOOST_PP_ADD(i, BOOST_PP_TUPLE_ELEM(2, 1, id_offset)), \
- var).value
+#define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_MEMBER_BIND_( \
+ r, offset, i, var) \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_VAR_( \
+ BOOST_PP_ADD(offset, i))
 
 // Adapted from `BOOST_SCOPE_EXIT_AUX_ARG_DECL()`.
 #define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_BIND_DECL_( \
@@ -128,13 +134,6 @@
     BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_BIND_DECL_( \
             r, id_typename_offset, i, var, is_const)
     
-// Adapted from `BOOST_SCOPE_EXIT_AUX_ARG()`.
-#define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_BIND_( \
- r, id_offset, i, var) \
- BOOST_PP_COMMA_IF(i) \
- BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_BIND_VALUE_( \
- id_offset, i, var)
-
 #define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_BIND_DECL_( \
         r, id_typename_offset, i, var) \
     BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_BIND_DECL_ENUM_( \
@@ -145,6 +144,43 @@
     BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_BIND_DECL_ENUM_( \
             r, id_typename_offset, i, var, 1 /* force const */)
 
+#define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_DECL_( \
+ r, id_typename_offset, i, var, is_const) \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_BIND_DECL_( \
+ r, id_typename_offset, i, \
+ & /* all bind member vars are refs to ScopeExit struct members */ \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_VAR_(\
+ BOOST_PP_ADD(i, BOOST_PP_TUPLE_ELEM(3, 2, \
+ id_typename_offset))), \
+ is_const) \
+ ; /* end member variable declaration */
+
+#define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_BIND_MEMBER_DECL_( \
+ r, id_typename_offset, i, var) \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_DECL_( \
+ r, id_typename_offset, i, var, 0 /* do not force const */) \
+
+#define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_CONST_BIND_MEMBER_DECL_( \
+ r, id_typename_offset, i, var) \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_DECL_( \
+ r, id_typename_offset, i, var, 1 /* force const */) \
+
+// Adapted from `BOOST_SCOPE_EXIT_AUX_ARG()`.
+#define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_INIT_( \
+ r, id_offset, i, var) \
+ BOOST_PP_COMMA_IF(i) \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_VAR_( \
+ BOOST_PP_ADD(i, BOOST_PP_TUPLE_ELEM(2, 1, id_offset))) \
+ ( /* member variable initialization */ \
+ static_cast< BOOST_SCOPE_EXIT_AUX_PARAMS_T( \
+ BOOST_PP_TUPLE_ELEM(2, 0, id_offset))* >( \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_BIND_PARAM_)-> \
+ BOOST_SCOPE_EXIT_AUX_PARAM( \
+ BOOST_PP_TUPLE_ELEM(2, 0, id_offset), \
+ BOOST_PP_ADD(i, BOOST_PP_TUPLE_ELEM(2, 1, id_offset)), \
+ var).value \
+ )
+
 // Typeof type-definitions.
 
 #define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_TYPEDEF_( \
@@ -179,26 +215,25 @@
                 BOOST_LOCAL_AUX_PP_SIGN_PARAMS_UNBIND(sign_params)) \
     )
 
-// Functor `operator()`.
+// Functor call operations.
 
 #define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_CALL_(z, \
+ defaults_n, \
         sign_params, \
         unbinds, \
         const_binds, has_const_bind_this, \
         binds, has_bind_this, \
         id, typename_keyword) \
- BOOST_LOCAL_AUX_SYMBOL_RESULT_TYPE(id) \
- operator()( \
- BOOST_PP_LIST_FOR_EACH_I( \
- BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_UNBIND_ARG_DECL_, \
- typename_keyword, unbinds) \
- ) { \
+ inline BOOST_LOCAL_AUX_SYMBOL_RESULT_TYPE(id) operator()( \
+ BOOST_PP_LIST_FOR_EACH_I( \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_UNBIND_ARG_DECL_, \
+ typename_keyword, unbinds) \
+ ) { \
         /* just forward call to member function with local func name */ \
         return BOOST_LOCAL_AUX_SYMBOL_BODY_FUNCTION_NAME( \
             BOOST_PP_LIST_FOR_EACH_I( \
- BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_BIND_, \
- (id, 0 /* no offset */), \
- const_binds) \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_MEMBER_BIND_, \
+ 0 /* no offset */, const_binds) \
             /* pass plain binds */ \
             BOOST_PP_COMMA_IF( \
                 BOOST_PP_BITAND( \
@@ -207,13 +242,10 @@
                 ) \
             ) \
             BOOST_PP_LIST_FOR_EACH_I( \
- BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_BIND_, \
- (id \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_MEMBER_BIND_, \
                     /* offset param index of # of preceeding */ \
                     /* const-bind params (could be 0)*/ \
- , BOOST_PP_LIST_SIZE(const_binds) \
- ), \
- binds) \
+ BOOST_PP_LIST_SIZE(const_binds), binds) \
             /* pass bind `this` */ \
             BOOST_PP_COMMA_IF( \
                 BOOST_PP_BITAND( \
@@ -226,8 +258,7 @@
             ) \
             BOOST_PP_EXPR_IIF( \
                     BOOST_PP_BITOR(has_const_bind_this, has_bind_this), \
- BOOST_LOCAL_AUX_SYMBOL_BINDS_VARIABLE_NAME-> \
- BOOST_LOCAL_AUX_FUNCTION_CODE_BIND_THIS_NAME \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_BIND_MEMBER_THIS_ \
             ) \
             /* pass unbind params */ \
             BOOST_PP_COMMA_IF( \
@@ -248,83 +279,151 @@
         ); \
     }
 
+#define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_STATIC_CALL_FUNC_( \
+ z, defaults_n, unused) \
+ BOOST_LOCAL_AUX_INTERNAL_SYMBOL(BOOST_PP_CAT(call, defaults_n))
+
+#define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_STATIC_CALL_FUNC_PTR_( \
+ z, defaults_n, unused) \
+ &BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_STATIC_CALL_FUNC_( \
+ z, defaults_n, unused)
+
+#define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_STATIC_CALL_(z, \
+ defaults_n, \
+ sign_params, \
+ unbinds, \
+ const_binds, has_const_bind_this, \
+ binds, has_bind_this, \
+ id, typename_keyword) \
+ inline static BOOST_LOCAL_AUX_SYMBOL_RESULT_TYPE(id) \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_STATIC_CALL_FUNC_(z, defaults_n, ~)( \
+ void* object \
+ BOOST_PP_COMMA_IF(BOOST_PP_LIST_IS_CONS(unbinds)) \
+ BOOST_PP_LIST_FOR_EACH_I( \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_UNBIND_ARG_DECL_, \
+ typename_keyword, unbinds) \
+ ) { \
+ /* run-time: casting object to this class type and forward call to */ \
+ /* `operator()` (this performs better than doing multiple casting */ \
+ /* or using a casted object local variable here to call body */ \
+ /* directly from here without passing via `operator()`) */ \
+ /* compliance: passing local class type to `static_cast` is fully */ \
+ /* ISO C++ compliant because `static_cast` is not a template (even */ \
+ /* if its syntax resembles a function template call) in fact even */ \
+ /* in C is legal to cast to a local struct (using C-style casting) */ \
+ return static_cast< BOOST_LOCAL_AUX_SYMBOL_FUNCTOR_CLASS_NAME(id)* >( \
+ object)->operator()( \
+ BOOST_PP_LIST_FOR_EACH_I( \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_UNBIND_ARG_NAME_ENUM_, \
+ ~, unbinds) \
+ ); \
+ }
+
 // Return unbind params but without last (default) params specified by count.
 #define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_UNBIND_REMOVE_LAST_N_(n, \
         unbinds) \
     BOOST_PP_LIST_FIRST_N(BOOST_PP_SUB(BOOST_PP_LIST_SIZE(unbinds), n), \
             unbinds)
 
-#define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_CALL_FOR_DEFAULTS_(z, \
- n, params_unbinds_constbinds_hasconstthis_binds_hasthis_id_typename) \
- BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_CALL_(z \
- , BOOST_PP_TUPLE_ELEM(8, 0, \
- params_unbinds_constbinds_hasconstthis_binds_hasthis_id_typename) \
- /* remove last n default params */ \
- , BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_UNBIND_REMOVE_LAST_N_(n, \
- BOOST_PP_TUPLE_ELEM(8, 1, \
- params_unbinds_constbinds_hasconstthis_binds_hasthis_id_typename) \
- ) \
- , BOOST_PP_TUPLE_ELEM(8, 2, \
- params_unbinds_constbinds_hasconstthis_binds_hasthis_id_typename) \
- , BOOST_PP_TUPLE_ELEM(8, 3, \
- params_unbinds_constbinds_hasconstthis_binds_hasthis_id_typename) \
- , BOOST_PP_TUPLE_ELEM(8, 4, \
- params_unbinds_constbinds_hasconstthis_binds_hasthis_id_typename) \
- , BOOST_PP_TUPLE_ELEM(8, 5, \
- params_unbinds_constbinds_hasconstthis_binds_hasthis_id_typename) \
- , BOOST_PP_TUPLE_ELEM(8, 6, \
- params_unbinds_constbinds_hasconstthis_binds_hasthis_id_typename) \
- , BOOST_PP_TUPLE_ELEM(8, 7, \
- params_unbinds_constbinds_hasconstthis_binds_hasthis_id_typename) \
+#define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_CALL_FOR_DEFAULTS_(z, n, \
+ op_params_unbinds_constbinds_hasconstthis_binds_hasthis_id_typename) \
+ BOOST_PP_EXPAND( \
+ BOOST_PP_TUPLE_ELEM(9, 0, \
+ op_params_unbinds_constbinds_hasconstthis_binds_hasthis_id_typename) \
+ ( z, n \
+ , BOOST_PP_TUPLE_ELEM(9, 1, \
+ op_params_unbinds_constbinds_hasconstthis_binds_hasthis_id_typename) \
+ /* remove last n default params */ \
+ , BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_UNBIND_REMOVE_LAST_N_(n, \
+ BOOST_PP_TUPLE_ELEM(9, 2, \
+ op_params_unbinds_constbinds_hasconstthis_binds_hasthis_id_typename) \
+ ) \
+ , BOOST_PP_TUPLE_ELEM(9, 3, \
+ op_params_unbinds_constbinds_hasconstthis_binds_hasthis_id_typename) \
+ , BOOST_PP_TUPLE_ELEM(9, 4, \
+ op_params_unbinds_constbinds_hasconstthis_binds_hasthis_id_typename) \
+ , BOOST_PP_TUPLE_ELEM(9, 5, \
+ op_params_unbinds_constbinds_hasconstthis_binds_hasthis_id_typename) \
+ , BOOST_PP_TUPLE_ELEM(9, 6, \
+ op_params_unbinds_constbinds_hasconstthis_binds_hasthis_id_typename) \
+ , BOOST_PP_TUPLE_ELEM(9, 7, \
+ op_params_unbinds_constbinds_hasconstthis_binds_hasthis_id_typename) \
+ , BOOST_PP_TUPLE_ELEM(9, 8, \
+ op_params_unbinds_constbinds_hasconstthis_binds_hasthis_id_typename) \
+ ) /* end `op_macro(...)` */ \
+ ) /* end expand */
+
+#define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MEMBER_INITS_( \
+ const_binds, has_const_bind_this, \
+ binds, has_bind_this, \
+ id) \
+ BOOST_PP_EXPR_IIF(BOOST_PP_BITOR(BOOST_PP_BITOR(BOOST_PP_BITOR( \
+ BOOST_PP_LIST_IS_CONS(const_binds), BOOST_PP_LIST_IS_CONS(binds)), \
+ has_bind_this), has_const_bind_this), \
+ : \
+ ) \
+ /* init const binds */ \
+ BOOST_PP_LIST_FOR_EACH_I( \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_INIT_,\
+ (id, 0 /* no offset */), \
+ const_binds) \
+ /* init plain binds */ \
+ BOOST_PP_COMMA_IF( \
+ BOOST_PP_BITAND( \
+ BOOST_PP_LIST_IS_CONS(const_binds) \
+ , BOOST_PP_LIST_IS_CONS(binds) \
+ ) \
+ ) \
+ BOOST_PP_LIST_FOR_EACH_I( \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_INIT_,\
+ (id \
+ /* offset param index of # of preceeding */ \
+ /* const-bind params (could be 0)*/ \
+ , BOOST_PP_LIST_SIZE(const_binds) \
+ ), \
+ binds) \
+ /* init `this` bind (const or not) */ \
+ BOOST_PP_COMMA_IF( \
+ BOOST_PP_BITAND( \
+ BOOST_PP_BITOR( \
+ BOOST_PP_LIST_IS_CONS(const_binds) \
+ , BOOST_PP_LIST_IS_CONS(binds) \
+ ) \
+ , BOOST_PP_BITOR(has_const_bind_this, has_bind_this) \
+ ) \
+ ) \
+ BOOST_PP_EXPR_IIF(BOOST_PP_BITOR(has_const_bind_this, has_bind_this), \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_BIND_MEMBER_THIS_( \
+ static_cast< BOOST_SCOPE_EXIT_AUX_PARAMS_T(id)* >( \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_BIND_PARAM_)-> \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_BIND_THIS_NAME \
+ ) \
     )
 
 // Functor class.
 
 // Adapted from `BOOST_SCOPE_EXIT_AUX_IMPL()`.
 #define BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_(sign_params, \
- unbinds, defaults_count, \
+ unbinds, default_count, \
         const_binds, has_const_bind_this, \
         binds, has_bind_this, \
         id, typename_keyword) \
- class BOOST_LOCAL_AUX_SYMBOL_FUNCTOR_CLASS_NAME(id) : \
- public ::boost::local::aux::abstract_function< \
- BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_F_( \
- sign_params, id, 0 /* no type */, ~), \
- defaults_count> { \
+ class BOOST_LOCAL_AUX_SYMBOL_FUNCTOR_CLASS_NAME(id) \
+ /* run-time: do not use base class to allow for compiler optimizations */ \
+ { \
+ /* function type */ \
         typedef BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_F_(sign_params, id, \
                 1 /* has type */, BOOST_LOCAL_AUX_SYMBOL_FUNCTION_TYPE); \
- public: \
- /* constructor */ \
- explicit BOOST_LOCAL_AUX_SYMBOL_FUNCTOR_CLASS_NAME(id)( \
- void* binding_data) \
- BOOST_PP_EXPR_IIF(BOOST_PP_EXPAND( /* expand for MSVC */ \
- BOOST_LOCAL_AUX_PP_SIGN_PARAMS_HAVE_ANY_BIND(sign_params)),\
- /* member init (not a macro call) */ \
- : BOOST_LOCAL_AUX_SYMBOL_BINDS_VARIABLE_NAME(static_cast< \
- BOOST_SCOPE_EXIT_AUX_PARAMS_T(id)*>(binding_data)) \
- ) \
- { \
- /* init needs func name so programmed later by `NAME` macro */ \
- BOOST_LOCAL_AUX_SYMBOL_INIT_RECURSION_FUNCTION_NAME(); \
- } \
- /* implement base functor `operator()` (and for all default params) */ \
- BOOST_PP_REPEAT( \
- /* PP_INC to handle no dflt (EXPAND for MVSC) */ \
- BOOST_PP_EXPAND(BOOST_PP_INC(defaults_count)), \
- BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_CALL_FOR_DEFAULTS_,\
- (sign_params, unbinds, const_binds, has_const_bind_this, \
- binds, has_bind_this, id, typename_keyword) ) \
- private: \
- /* this type symbol cannot have ID postfix because it is used */ \
- /* the `NAME` macro (because this symbol is within functor class */ \
- /* it doesn't have to have ID postfix). */ \
+ /* functor type -- this type cannot have ID postfix because it is */ \
+ /* used the `NAME` macro (this symbol is within functor class so */ \
+ /* it does not have to have ID postfix) */ \
         typedef ::boost::local::function<BOOST_LOCAL_AUX_SYMBOL_FUNCTION_TYPE, \
- defaults_count> BOOST_LOCAL_AUX_SYMBOL_FUNCTOR_TYPE; \
- /* these types are qualified with extra eventual const and/or & if */ \
- /* their variables are bound by const and/or & (this is because */ \
- /* it is difficult strip the eventual & given that the var name is */ \
- /* always attached to the & symbol plus programmers can always */ \
- /* remove const& using type traits) */ \
+ default_count> BOOST_LOCAL_AUX_SYMBOL_FUNCTOR_TYPE; \
+ /* typeof types -- these types are qualified with extra eventual */ \
+ /* const and/or & if their variables are bound by const and/or & */ \
+ /* (this is because it is not possible to strip the eventual & */ \
+ /* given that the var name is always attached to the & symbol plus */ \
+ /* programmers can always remove const& using type traits) */ \
         /* const bind typeof types */ \
         BOOST_PP_LIST_FOR_EACH_I( \
                 BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_CONST_TYPEDEF_, \
@@ -338,7 +437,7 @@
                   /* const-bindparams (could be 0)*/ \
                   BOOST_PP_LIST_SIZE(const_binds)),\
                 binds) \
- /* this (const or not) bind type */ \
+ /* this (const or not) bind typeof type */ \
         BOOST_PP_EXPR_IIF(has_const_bind_this, \
             typedef \
             BOOST_LOCAL_AUX_SYMBOL_TYPEOF_TYPE( \
@@ -354,15 +453,81 @@
                 this /* must not use `this_` for TYPEOF_TYPE */ \
             ) ; /* end typedef */ \
         ) \
- /* bind params member variable (note -- signle bind param cannot */ \
- /* be represented as single member variables because their names */ \
- /* might be prefixed by `&` so they are not know to pp) */ \
- BOOST_PP_EXPR_IIF(BOOST_PP_EXPAND( /* EXPAND for MSVC */ \
- BOOST_LOCAL_AUX_PP_SIGN_PARAMS_HAVE_ANY_BIND(sign_params)), \
- BOOST_SCOPE_EXIT_AUX_PARAMS_T(id)* \
- BOOST_LOCAL_AUX_SYMBOL_BINDS_VARIABLE_NAME; \
+ public: \
+ /* constructor */ \
+ inline explicit BOOST_LOCAL_AUX_SYMBOL_FUNCTOR_CLASS_NAME(id)( \
+ void* BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_BIND_PARAM_) \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_MEMBER_INITS_(const_binds, \
+ has_const_bind_this, binds, has_bind_this, id) \
+ { /* do nothing */ } \
+ /* run-time: implement `operator()` (and for all default params) so */ \
+ /* this obj can be used directly as a functor for C++03 extensions */ \
+ /* and optimized macros */ \
+ BOOST_PP_REPEAT( \
+ /* PP_INC to handle no dflt (EXPAND for MVSC) */ \
+ BOOST_PP_EXPAND(BOOST_PP_INC(default_count)), \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_CALL_FOR_DEFAULTS_,\
+ ( BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_CALL_, sign_params \
+ , unbinds, const_binds, has_const_bind_this, binds \
+ , has_bind_this, id, typename_keyword ) \
+ ) \
+ /* compliance: trick to pass this local class as a template param */ \
+ /* on ISO C++ without non C++03 extension */ \
+ /* performance: this trick introduced _one_ indirect function call */ \
+ /* via a function pointer that cannot be inlined by the complier */ \
+ /* thus increasing run-time (also another trick using a base */ \
+ /* interface class was investigated but virtual calls also cannot */ \
+ /* inlined plus they require virtual table lookups to the "virtual */ \
+ /* call trick" measured longer run-times than this "static call */ \
+ /* trick") */ \
+ BOOST_PP_REPEAT( \
+ /* PP_INC to handle no dflt (EXPAND for MVSC) */ \
+ BOOST_PP_EXPAND(BOOST_PP_INC(default_count)), \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_CALL_FOR_DEFAULTS_,\
+ ( BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_STATIC_CALL_, sign_params \
+ , unbinds, const_binds, has_const_bind_this, binds \
+ , has_bind_this, id, typename_keyword ) \
+ ) \
+ inline static void BOOST_LOCAL_AUX_SYMBOL_INIT_CALL_FUNCTION_NAME( \
+ void* object, BOOST_LOCAL_AUX_SYMBOL_FUNCTOR_TYPE& functor) { \
+ functor.BOOST_LOCAL_AUX_SYMBOL_INIT_CALL_FUNCTION_NAME(object, \
+ BOOST_PP_ENUM( \
+ /* PP_INC to handle no dflt (EXPAND for MVSC) */ \
+ BOOST_PP_EXPAND(BOOST_PP_INC(default_count)), \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_STATIC_CALL_FUNC_PTR_, \
+ ~) \
+ ); \
+ } \
+ private: \
+ /* run-time: it is faster if call `operator()` just accesses member */ \
+ /* references to the ScopeExit struct instead of accessing the bind */ \
+ /* struct at each call (these mem refs are init by the constructor) */ \
+ BOOST_PP_LIST_FOR_EACH_I( /* const bind member references */ \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_CONST_BIND_MEMBER_DECL_,\
+ (id, typename_keyword, 0 /* no offset */), \
+ const_binds) \
+ BOOST_PP_LIST_FOR_EACH_I( /* bind member references */ \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_BIND_MEMBER_DECL_, \
+ (id, typename_keyword, \
+ /* offset param index of # of preceeding */ \
+ /* const-bindparams (could be 0)*/ \
+ BOOST_PP_LIST_SIZE(const_binds)),\
+ binds) \
+ BOOST_PP_EXPR_IIF(has_const_bind_this, /* const bind `this` mem ref */ \
+ typename_keyword ::boost::local::aux::add_pointed_const< \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_BIND_THIS_TYPE(id) \
+ >::type \
+ & /* all bind member vars are refs to ScopeExit struct members */ \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_BIND_MEMBER_THIS_ \
+ ; /* end member variable declaration */ \
+ ) \
+ BOOST_PP_EXPR_IIF(has_bind_this, /* bind `this` member reference */ \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_BIND_THIS_TYPE(id) \
+ & /* all bind member vars are refs to ScopeExit struct members */ \
+ BOOST_LOCAL_AUX_FUNCTION_CODE_FUNCTOR_BIND_MEMBER_THIS_ \
+ ; /* end member variable declaration */ \
         ) \
- /* this allows for nesting (local functions, blocks, and exits) as */ \
+ /* this decl allows for nesting (local functions, etc) as */ \
         /* it makes the args variable visible within the body code (which */ \
         /* cannot be static); this is for compilation only as the args */ \
         /* variable is actually declared by the 1st enclosing local func */ \
@@ -371,7 +536,7 @@
         /* body function (unfortunately, cannot be static to allow access */ \
         /* to member var with local function name for recursion but doing */ \
         /* so also allows the body to misuse `this` instead of `this_`) */ \
- BOOST_LOCAL_AUX_SYMBOL_RESULT_TYPE(id) \
+ inline BOOST_LOCAL_AUX_SYMBOL_RESULT_TYPE(id) \
         BOOST_LOCAL_AUX_SYMBOL_BODY_FUNCTION_NAME( \
                 /* const binds */ \
                 BOOST_PP_LIST_FOR_EACH_I( \

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-13 11:34:46 EDT (Wed, 13 Apr 2011)
@@ -8,74 +8,83 @@
 #define BOOST_LOCAL_AUX_FUNCTION_NAME_HPP_
 
 #include "../symbol.hpp"
+#include "../config.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_INIT_RECURSION_FUNC_ \
+ BOOST_LOCAL_AUX_INTERNAL_SYMBOL(init_recursion)
+
 #define BOOST_LOCAL_AUX_FUNCTION_NAME_END_LOCAL_FUNCTOR_( \
- local_functor_name, local_function_name, \
- is_local_function_member_public, id) \
+ local_function_name, local_functor_name, nonlocal_functor_name, id) \
     /* `PARAMS() { ... }` expandsion here -- still within functor class */ \
     /* class functor ## __LINE__ { ... */ \
- BOOST_PP_IIF(is_local_function_member_public, \
+ 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: \
- ) \
+ /* run-time: even when optimizing, recursive calls cannot be */ \
+ /* optimized (i.e., they must be via the non-local functor) */ \
+ /* because this cannot be a mem ref because its name is not known */ \
+ /* by the constructor so it cannot be set by the mem init list */ \
         BOOST_LOCAL_AUX_SYMBOL_FUNCTOR_TYPE local_function_name; \
- private: \
- /* called by the constructor to init member variable for recursion */ \
- void BOOST_LOCAL_AUX_SYMBOL_INIT_RECURSION_FUNCTION_NAME() { \
- local_function_name = *this; \
+ /* run-time: the `init_recursion()` function cannot be called by */ \
+ /* the constructor to allow for compiler optimization (inlining) */ \
+ /* so it must be public */ \
+ inline void BOOST_LOCAL_AUX_FUNCTION_NAME_INIT_RECURSION_FUNC_( \
+ BOOST_LOCAL_AUX_SYMBOL_FUNCTOR_TYPE& functor) { \
+ local_function_name = functor; \
         } \
- /* 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 */ \
- } 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(local_functor_name.local_function_name) const \
- local_function_name(local_functor_name);
+ /* local functor can be passed as tparam only on C++03 (faster) */ \
+ } local_functor_name(BOOST_LOCAL_AUX_SYMBOL_ARGS_VARIABLE_NAME.value); \
+ /* non-local functor can always be passed as tparam (but slower) */ \
+ BOOST_TYPEOF(local_functor_name.local_function_name) \
+ nonlocal_functor_name; \
+ /* run-time: the following order in which the functors are set is */ \
+ /* important to allow for compiler optimization (changing this order */ \
+ /* and/or moving some of these sets into the functor constructors might */ \
+ /* prevent compiler optimizations) */ \
+ local_functor_name.BOOST_LOCAL_AUX_FUNCTION_NAME_INIT_RECURSION_FUNC_( \
+ nonlocal_functor_name); \
+ local_functor_name.BOOST_LOCAL_AUX_SYMBOL_INIT_CALL_FUNCTION_NAME( \
+ &local_functor_name, nonlocal_functor_name);
+
+#define BOOST_LOCAL_AUX_FUNCTION_NAME_FUNCTOR_(local_function_name) \
+ BOOST_LOCAL_AUX_INTERNAL_SYMBOL(local_function_name)
 
 // PUBLIC //
 
 // Limitation: This is faster (smaller run-time than `FUNCION_NAME`) but it
-// cannot be passed as template parameter on ISO C++.
+// cannot be passed as template parameter on ISO C++ but it can on C++03.
 #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__)
+ BOOST_LOCAL_AUX_FUNCTION_NAME_END_LOCAL_FUNCTOR_( \
+ local_function_name, \
+ local_function_name, \
+ BOOST_LOCAL_AUX_FUNCTION_NAME_FUNCTOR_(local_function_name), \
+ __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
+// if can use C++03 (no ISO C++) 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)
+#ifdef BOOST_LOCAL_AUX_CONFIG_LOCAL_CLASS_AS_TEMPLATE_PARAMETER
+
+#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__)
+
+#define BOOST_LOCAL_AUX_FUNCTION_NAME(local_function_name) \
+ BOOST_LOCAL_AUX_FUNCTION_NAME_END_LOCAL_FUNCTOR_( \
+ local_function_name, \
+ BOOST_LOCAL_AUX_FUNCTION_NAME_FUNCTOR_(local_function_name), \
+ local_function_name, \
+ __LINE__)
+
 #endif
 
 #endif // #include guard

Modified: sandbox/local/boost/local/aux_/symbol.hpp
==============================================================================
--- sandbox/local/boost/local/aux_/symbol.hpp (original)
+++ sandbox/local/boost/local/aux_/symbol.hpp 2011-04-13 11:34:46 EDT (Wed, 13 Apr 2011)
@@ -92,5 +92,8 @@
 #define BOOST_LOCAL_AUX_SYMBOL_INIT_RECURSION_FUNCTION_NAME \
     BOOST_LOCAL_AUX_INTERNAL_SYMBOL(init_recursion)
 
+#define BOOST_LOCAL_AUX_SYMBOL_INIT_CALL_FUNCTION_NAME \
+ BOOST_LOCAL_AUX_INTERNAL_SYMBOL(init_call)
+
 #endif // #include guard
 

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-13 11:34:46 EDT (Wed, 13 Apr 2011)
@@ -12,14 +12,14 @@
     double sum = 0.0;
     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(S);
+ std::fill(v.begin(), v.end(), 1.0);
+
     for (size_t n = 0; n < N; ++n) {
         std::for_each(v.begin(), v.end(), add);
     }


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