|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r77917 - in trunk: boost boost/local_function/aux_/macro boost/local_function/aux_/macro/code_ boost/local_function/aux_/preprocessor/traits libs/local_function/test
From: lorcaminiti_at_[hidden]
Date: 2012-04-11 13:14:01
Author: lcaminiti
Date: 2012-04-11 13:14:00 EDT (Wed, 11 Apr 2012)
New Revision: 77917
URL: http://svn.boost.org/trac/boost/changeset/77917
Log:
Implemented a trick for NAME not to use BOOST_TYPEOF without requiring to repeat the function type (doing a typedef on the local class so to access the functor type in NAME).
Removed:
trunk/boost/local_function/aux_/preprocessor/traits/name.hpp
Text files modified:
trunk/boost/local_function.hpp | 9
trunk/boost/local_function/aux_/macro/code_/functor.hpp | 8
trunk/boost/local_function/aux_/macro/name.hpp | 267 +++++++++++++++++++++------------------
trunk/libs/local_function/test/add_typed.cpp | 6
trunk/libs/local_function/test/add_typed_seq.cpp | 2
5 files changed, 157 insertions(+), 135 deletions(-)
Modified: trunk/boost/local_function.hpp
==============================================================================
--- trunk/boost/local_function.hpp (original)
+++ trunk/boost/local_function.hpp 2012-04-11 13:14:00 EDT (Wed, 11 Apr 2012)
@@ -14,7 +14,6 @@
#include <boost/local_function/aux_/macro/name.hpp>
#include <boost/local_function/aux_/macro/typeof.hpp>
#include <boost/local_function/aux_/preprocessor/traits/decl.hpp>
-#include <boost/local_function/aux_/preprocessor/traits/name.hpp>
#include <boost/local_function/detail/preprocessor/line_counter.hpp>
#include <boost/local_function/detail/preprocessor/void_list.hpp>
#include <boost/config.hpp>
@@ -46,12 +45,12 @@
BOOST_LOCAL_FUNCTION_DETAIL_PP_LINE_COUNTER, 1, __VA_ARGS__)
#endif // VARIADIC
-#define BOOST_LOCAL_FUNCTION_NAME(name) \
+#define BOOST_LOCAL_FUNCTION_NAME(qualified_function_name) \
BOOST_LOCAL_FUNCTION_AUX_NAME(0, /* not within template */ \
- BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS(name))
-#define BOOST_LOCAL_FUNCTION_NAME_TPL(name) \
+ qualified_function_name)
+#define BOOST_LOCAL_FUNCTION_NAME_TPL(qualified_function_name) \
BOOST_LOCAL_FUNCTION_AUX_NAME(1, /* within template */ \
- BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS(name))
+ qualified_function_name)
#define BOOST_LOCAL_FUNCTION_TYPEOF(bound_variable_name) \
BOOST_LOCAL_FUNCTION_AUX_TYPEOF_TYPE(bound_variable_name)
Modified: trunk/boost/local_function/aux_/macro/code_/functor.hpp
==============================================================================
--- trunk/boost/local_function/aux_/macro/code_/functor.hpp (original)
+++ trunk/boost/local_function/aux_/macro/code_/functor.hpp 2012-04-11 13:14:00 EDT (Wed, 11 Apr 2012)
@@ -687,10 +687,11 @@
#define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_( \
id, typename01, decl_traits, params, \
default_count, const_binds, has_const_bind_this, binds, has_bind_this) \
- class BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CLASS_TYPE_(id) \
+ typedef class BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CLASS_TYPE_(id) \
/* run-time: do not use base class to allow for compiler optimizations */ \
{ \
/* function type */ \
+ private: \
typedef \
BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_F_(id, typename01, \
decl_traits, 1 /* has type */, \
@@ -698,7 +699,9 @@
; \
/* 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) */ \
+ /* it does not have to have ID postfix), must be public so it */ \
+ /* can be accessed by `NAME` macro from outside this class */ \
+ public: \
typedef BOOST_PP_EXPR_IIF(typename01, typename) \
BOOST_IDENTITY_TYPE(( /* IDENTITY for template param comma */ \
::boost::local_function::aux::function< \
@@ -714,6 +717,7 @@
)) \
BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_TYPE \
; \
+ private: \
BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_TYPEOF_TYPEDEFS_( \
id, typename01, \
const_binds, has_const_bind_this, binds, has_bind_this) \
Modified: trunk/boost/local_function/aux_/macro/name.hpp
==============================================================================
--- trunk/boost/local_function/aux_/macro/name.hpp (original)
+++ trunk/boost/local_function/aux_/macro/name.hpp 2012-04-11 13:14:00 EDT (Wed, 11 Apr 2012)
@@ -8,14 +8,13 @@
#ifndef BOOST_LOCAL_FUNCTION_AUX_NAME_HPP_
#define BOOST_LOCAL_FUNCTION_AUX_NAME_HPP_
-
#include <boost/local_function/config.hpp>
#include <boost/local_function/aux_/macro/decl.hpp>
#include <boost/local_function/aux_/macro/code_/functor.hpp>
-#include <boost/local_function/aux_/preprocessor/traits/name.hpp>
+#include <boost/local_function/detail/preprocessor/keyword/recursive.hpp>
+#include <boost/local_function/detail/preprocessor/keyword/inline.hpp>
#include <boost/local_function/aux_/function.hpp>
#include <boost/local_function/aux_/symbol.hpp>
-#include <boost/typeof/typeof.hpp>
#include <boost/preprocessor/control/iif.hpp>
#include <boost/preprocessor/control/expr_iif.hpp>
#include <boost/preprocessor/logical/bitor.hpp>
@@ -23,85 +22,60 @@
// PRIVATE //
+#define BOOST_LOCAL_FUNCTION_AUX_NAME_LOCAL_TYPE_(local_function_name) \
+ BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (local_type)(local_function_name) )
+
#define BOOST_LOCAL_FUNCTION_AUX_NAME_INIT_RECURSION_FUNC_ \
BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (init_recursion) )
-#define BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_FUNC_(name_traits) \
- BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS_IS_RECURSIVE( \
- name_traits), \
- BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS_FUNCTION_NAME \
+#define BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_FUNC_( \
+ is_recursive, local_function_name) \
+ BOOST_PP_IIF(is_recursive, \
+ local_function_name \
, \
BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (nonrecursive_local_function_name) ) \
- BOOST_PP_TUPLE_EAT(1) \
- )(name_traits)
-
-#define BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_TYPEOF_( \
- typename01, name_traits, local_functor_name) \
- BOOST_PP_IIF(typename01, \
- BOOST_TYPEOF_TPL \
- , \
- BOOST_TYPEOF \
- )(local_functor_name.BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_FUNC_( \
- name_traits))
-
-#define BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_TYPED_( \
- typename01, name_traits, local_functor_name) \
- BOOST_PP_EXPR_IIF(typename01, typename) \
- BOOST_IDENTITY_TYPE((::boost::local_function::aux::function< \
- BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS_FUNCTION_TYPE( \
- name_traits) \
- , BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS_DEFAULTS(name_traits) \
- >))
-
-#define BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_TYPE_( \
- typename01, name_traits, local_functor_name) \
- BOOST_PP_IIF(BOOST_PP_IS_EMPTY( \
- BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS_FUNCTION_TYPE( \
- name_traits)), \
- BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_TYPEOF_ \
- , \
- BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_TYPED_ \
- )(typename01, name_traits, local_functor_name)
+ )
-#define BOOST_LOCAL_FUNCTION_AUX_NAME_LOCAL_FUNCTOR_(typename01, name_traits, \
+#define BOOST_LOCAL_FUNCTION_AUX_NAME_END_LOCAL_FUNCTOR_(typename01, \
+ local_function_name, is_recursive, \
local_functor_name, nonlocal_functor_name) \
- /* `PARAMS() { ... }` expandsion here -- still within functor class */ \
- /* class functor ## __LINE__ { ... */ \
- 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 */ \
+ /* FUNCTION macro expanded to: typedef class functor ## __LINE__ { ... */ \
+ BOOST_PP_EXPR_IIF(is_recursive, \
+ /* member var with function name for recursive calls; it cannot be */ \
/* `const` because it is init after construction (because */ \
/* constructor doesn't know local function name) */ \
/* 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 */ \
+ private: \
BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_TYPE \
- BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_FUNC_(name_traits); \
- BOOST_PP_EXPR_IIF(BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS_IS_RECURSIVE(\
- name_traits), \
- /* 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_FUNCTION_AUX_NAME_INIT_RECURSION_FUNC_( \
- BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_TYPE& functor) { \
- BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS_FUNCTION_NAME( \
- name_traits) = functor; \
- } \
- ) \
+ BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_FUNC_(is_recursive, \
+ local_function_name); \
+ /* run-time: the `init_recursion()` function cannot be called */ \
+ /* by the constructor to allow for compiler optimization */ \
+ /* (inlining) so it must be public to be called (see below) */ \
+ public: \
+ inline void BOOST_LOCAL_FUNCTION_AUX_NAME_INIT_RECURSION_FUNC_( \
+ BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_TYPE& functor) { \
+ local_function_name = functor; \
+ } \
+ ) \
+ } BOOST_LOCAL_FUNCTION_AUX_NAME_LOCAL_TYPE_(local_function_name); \
/* local functor can be passed as tparam only on C++11 (faster) */ \
- } local_functor_name(BOOST_LOCAL_FUNCTION_AUX_DECL_ARGS_VAR.value); \
+ BOOST_LOCAL_FUNCTION_AUX_NAME_LOCAL_TYPE_(local_function_name) \
+ local_functor_name(BOOST_LOCAL_FUNCTION_AUX_DECL_ARGS_VAR.value); \
/* non-local functor can always be passed as tparam (but slower) */ \
- BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_TYPE_(typename01, name_traits, \
- local_functor_name) nonlocal_functor_name; /* functor variable */ \
+ BOOST_PP_EXPR_IIF(typename01, typename) \
+ BOOST_LOCAL_FUNCTION_AUX_NAME_LOCAL_TYPE_(local_function_name):: \
+ BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_TYPE \
+ nonlocal_functor_name; /* functor variable */ \
/* the order of the following 2 function calls cannot be changed */ \
/* because init_recursion uses the local_functor so the local_functor */ \
/* must be init first */ \
local_functor_name.BOOST_LOCAL_FUNCTION_AUX_FUNCTION_INIT_CALL_FUNC( \
&local_functor_name, nonlocal_functor_name); \
- BOOST_PP_EXPR_IIF(BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS_IS_RECURSIVE( \
- name_traits), \
+ BOOST_PP_EXPR_IIF(is_recursive, \
/* init recursion causes MSVC to not optimize local function not */ \
/* even when local functor is used as template parameter so no */ \
/* recursion unless all inlining optimizations are specified off */ \
@@ -112,71 +86,116 @@
#define BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_(local_function_name) \
BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (local_function_name) )
+// This can always be passed as a template parameters (on all compilers).
+// However, it is slower because it cannot be inlined.
+// Passed at tparam: Yes (on all C++). Inlineable: No. Recursive: No.
+#define BOOST_LOCAL_FUNCTION_AUX_NAME_(typename01, local_function_name) \
+ BOOST_LOCAL_FUNCTION_AUX_NAME_END_LOCAL_FUNCTOR_(typename01, \
+ local_function_name, \
+ /* local function is not recursive (because recursion and its */ \
+ /* initialization cannot be inlined even on C++11, */ \
+ /* so this allows optimization at least on C++11) */ \
+ 0 /* not recursive */ , \
+ /* local functor */ \
+ BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_(local_function_name), \
+ /* local function declared as non-local functor -- but it can */ \
+ /* be inlined only by C++11 and it cannot be recursive */ \
+ local_function_name)
+
+// This is faster on some compilers but not all (e.g., it is faster on GCC
+// because its optimization inlines it but not on MSVC). However, it cannot be
+// passed as a template parameter on non C++11 compilers.
+// Passed at tparam: Only on C++11. Inlineable: Yes. Recursive: No.
+#define BOOST_LOCAL_FUNCTION_AUX_NAME_INLINE_(typename01, local_function_name) \
+ BOOST_LOCAL_FUNCTION_AUX_NAME_END_LOCAL_FUNCTOR_(typename01, \
+ local_function_name, \
+ /* inlined local function is never recursive (because recursion */ \
+ /* and its initialization cannot be inlined)*/ \
+ 0 /* not recursive */ , \
+ /* inlined local function declared as local functor (maybe */ \
+ /* inlined even by non C++11 -- but it can be passed as */ \
+ /* template parameter only on C++11 */ \
+ local_function_name, \
+ /* non-local functor */ \
+ BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_(local_function_name))
+
+// This is slower on all compilers (C++11 and non) because recursion and its
+// initialization can never be inlined.
+// Passed at tparam: Yes. Inlineable: No. Recursive: Yes.
+#define BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_( \
+ typename01, local_function_name) \
+ BOOST_LOCAL_FUNCTION_AUX_NAME_END_LOCAL_FUNCTOR_(typename01, \
+ local_function_name, \
+ /* recursive local function -- but it cannot be inlined */ \
+ 1 /* recursive */ , \
+ /* local functor */ \
+ BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_(local_function_name), \
+ /* local function declared as non-local functor -- but it can */ \
+ /* be inlined only by C++11 */ \
+ local_function_name)
+
+// Inlined local functions are specified by `..._NAME(inline name)`.
+// They have more chances to be inlined for faster run-times by some compilers
+// (for example by GCC but not by MSVC). C++11 compilers can always inline
+// local functions even if they are not explicitly specified inline.
+#define BOOST_LOCAL_FUNCTION_AUX_NAME_PARSE_INLINE_( \
+ typename01, qualified_name) \
+ BOOST_PP_IIF(BOOST_PP_BITOR( \
+ BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS, \
+ BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_INLINE_FRONT( \
+ qualified_name)), \
+ /* on C++11 always use inlining because compilers might optimize */ \
+ /* it to be faster and it can also be passed as tparam */ \
+ BOOST_LOCAL_FUNCTION_AUX_NAME_INLINE_ \
+ , \
+ /* on non C++11 don't use liniling unless explicitly specified by */ \
+ /* programmers `inline name` the inlined local function cannot be */ \
+ /* passed as tparam */ \
+ BOOST_LOCAL_FUNCTION_AUX_NAME_ \
+ )(typename01, BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_REMOVE_FRONT( \
+ qualified_name))
+
+// Expand to 1 iff `recursive name` or `recursive inline name` or
+// `inline recursive name`.
+#define BOOST_LOCAL_FUNCTION_AUX_NAME_IS_RECURSIVE_(qualified_name) \
+ BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_RECURSIVE_FRONT( \
+ BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_REMOVE_FRONT( \
+ qualified_name \
+ ))
+
+// Revmoes `recursive`, `inline recursive`, and `recursive inline` from front.
+#define BOOST_LOCAL_FUNCTION_AUX_NAME_REMOVE_RECURSIVE_AND_INLINE_( \
+ qualified_name) \
+ BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RECURSIVE_REMOVE_FRONT( \
+ BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_REMOVE_FRONT( \
+ BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RECURSIVE_REMOVE_FRONT( \
+ qualified_name \
+ )))
+
+#define BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_REMOVE_(qualified_name) \
+ BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_AUX_NAME_IS_RECURSIVE_(qualified_name), \
+ BOOST_LOCAL_FUNCTION_AUX_NAME_REMOVE_RECURSIVE_AND_INLINE_ \
+ , \
+ qualified_name /* might be `name` or `inline name` */ \
+ BOOST_PP_TUPLE_EAT(1) \
+ )(qualified_name)
+
+// Recursive local function are specified by `..._NAME(recursive name)`.
+// They can never be inlined for faster run-time (not even by C++11 compilers).
+#define BOOST_LOCAL_FUNCTION_AUX_NAME_PARSE_RECURSIVE_( \
+ typename01, qualified_name) \
+ BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_AUX_NAME_IS_RECURSIVE_(qualified_name), \
+ /* recursion can never be inlined (not even on C++11) */ \
+ BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_ \
+ , \
+ BOOST_LOCAL_FUNCTION_AUX_NAME_PARSE_INLINE_ \
+ )(typename01, \
+ BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_REMOVE_(qualified_name))
+
// PUBLIC //
-// If !INLINE(name_traits) && !RECURSIVE(name_traits):
-// This can always be passed as a template parameters (on all compilers).
-// However, it is slower because it cannot be inlined.
-// If !INLINE(name_traits) && RECURSIVE(name_traits):
-// This is slower on all compilers (C++11 and non) because recursion and
-// its initialization can never be inlined.
-// If INLINE(name_traits) && !RECURSIVE(name_traits):
-// This is faster on some compilers but not all (e.g., it is faster on GCC
-// because its optimization inlines it but not on MSVC). However, it
-// cannot be passed as a template parameter on non C++11 compilers.
-// If INLINE(name_traits) && RECURSIVE(name_traits):
-// Same as RECURSIVE && !INLINE.
-#define BOOST_LOCAL_FUNCTION_AUX_NAME(typename01, name_traits) \
- BOOST_PP_EXPAND( \
- BOOST_LOCAL_FUNCTION_AUX_NAME_LOCAL_FUNCTOR_ \
- BOOST_PP_IIF( /* !RECURSIVE && (C++11 || INLINE) => FASTER */ \
- BOOST_PP_BITAND( \
- BOOST_PP_COMPL( \
- BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS_IS_RECURSIVE( \
- name_traits)) \
- , BOOST_PP_BITOR( \
- /* on C++11 always use inlining because compilers */ \
- /* might optimize it to be faster and it can also */ \
- /* be passed as template parameter */ \
- BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS \
- , BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS_IS_INLINE( \
- name_traits) \
- ) \
- ), \
- /* inlined local function declared as local functor: it maybe */ \
- /* always be inlined (faster) but it can be passed as template */ \
- /* parameter only by C++11 -- never recursive */ \
- ( \
- typename01 \
- , \
- name_traits \
- , \
- BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS_FUNCTION_NAME( \
- name_traits) \
- , \
- BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_( \
- BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS_FUNCTION_NAME( \
- name_traits)) \
- ) \
- , /* RECURSIVE || (!C++11 && !INLINE) => SLOWER */ \
- /* local function declared as non-local functor: it can always */ \
- /* be passed as template parameter but slower even on C++11 if */ \
- /* declared recursive -- it can be inlined (faster) only by */ \
- /* C++11 and if not recursive */ \
- ( \
- typename01 \
- , \
- name_traits \
- , \
- BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_( \
- BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS_FUNCTION_NAME( \
- name_traits)) \
- , \
- BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS_FUNCTION_NAME( \
- name_traits) \
- ) \
- ) \
- )
+#define BOOST_LOCAL_FUNCTION_AUX_NAME(typename01, qualified_name) \
+ BOOST_LOCAL_FUNCTION_AUX_NAME_PARSE_RECURSIVE_(typename01, qualified_name)
#endif // #include guard
Deleted: trunk/boost/local_function/aux_/preprocessor/traits/name.hpp
==============================================================================
--- trunk/boost/local_function/aux_/preprocessor/traits/name.hpp 2012-04-11 13:14:00 EDT (Wed, 11 Apr 2012)
+++ (empty file)
@@ -1,139 +0,0 @@
-
-#ifndef BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS_HPP_
-#define BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS_HPP_
-
-#include <boost/local_function/detail/preprocessor/keyword/recursive.hpp>
-#include <boost/local_function/detail/preprocessor/keyword/inline.hpp>
-#include <boost/preprocessor/control/iif.hpp>
-#include <boost/preprocessor/facilities/empty.hpp>
-#include <boost/preprocessor/tuple/elem.hpp>
-#include <boost/preprocessor/tuple/eat.hpp>
-
-// PRIVATE //
-
-// Inline and recursive qualifiers.
-
-// Precondition: !recursive01
-#define BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_RECURSUVE_2ND_CHECK_( \
- function_type, default_count, recursive01, inline01, name) \
- ( \
- function_type \
- , \
- default_count \
- , \
- BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_RECURSIVE_FRONT(name) \
- , \
- inline01 \
- , \
- BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RECURSIVE_REMOVE_FRONT(name) \
- )
-
-// Allows for inline and recursive to appear in swapped oder.
-#define BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_RECURSUVE_2ND_( \
- function_type, default_count, recursive01, inline01, name) \
- BOOST_PP_IIF(recursive01, \
- (function_type, default_count, recursive01, inline01, name) \
- BOOST_PP_TUPLE_EAT(5) \
- , \
- /* going via this macro allows to error if recursive given twice */ \
- BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_RECURSUVE_2ND_CHECK_ \
- )(function_type, default_count, recursive01, inline01, name)
-
-#define BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_INLINE_( \
- function_type, default_count, recursive01, name) \
- BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_RECURSUVE_2ND_( \
- function_type \
- , default_count \
- , recursive01 \
- , BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_INLINE_FRONT(name) \
- , BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_REMOVE_FRONT(name) \
- )
-
-#define BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_RECURSIVE_1ST_( \
- function_type, default_count, name) \
- BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_INLINE_( \
- function_type \
- , default_count \
- , BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_RECURSIVE_FRONT(name) \
- , BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RECURSIVE_REMOVE_FRONT(name) \
- )
-
-// Default parameter count (defaults).
-
-#define BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_DEFAULTS_TUPLE_( \
- function_type, defaults_name) \
- BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_RECURSIVE_1ST_(function_type, \
- BOOST_PP_TUPLE_ELEM(2, 0, defaults_name), \
- BOOST_PP_TUPLE_ELEM(2, 1, defaults_name))
-
-#define BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_DEFAULTS_SPLIT_(defaults) \
- defaults /* trait not optional, assumed 0 when not specified */ \
- , /* comma splits */
-
-// Precondition: name == `(default_count) ...`
-#define BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_DEFAULTS_YES_( \
- function_type, name) \
- BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_DEFAULTS_TUPLE_(function_type, ( \
- BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_DEFAULTS_SPLIT_ name))
-
-#define BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_DEFAULTS_NO_( \
- function_type, name) \
- BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_RECURSIVE_1ST_(function_type, \
- 0 /* assume no defaults if not specified */, name)
-
-#define BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_DEFAULTS_(ftype_name) \
- BOOST_PP_IIF(BOOST_PP_IS_UNARY(BOOST_PP_TUPLE_ELEM(2, 1, ftype_name)), \
- BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_DEFAULTS_YES_ \
- , \
- BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_DEFAULTS_NO_ \
- )(BOOST_PP_TUPLE_ELEM(2, 0, ftype_name), \
- BOOST_PP_TUPLE_ELEM(2, 1, ftype_name))
-
-// Function type (ftype).
-
-#define BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_FTYPE_SPLIT_(function_type) \
- function_type BOOST_PP_EMPTY /* optional trait */ \
- , /* comma splits */
-
-// Precondition: name == `(function_type) ...`
-#define BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_FTYPE_YES_(name) \
- BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_DEFAULTS_(( \
- BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_FTYPE_SPLIT_ name))
-
-#define BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_FTYPE_NO_(name) \
- BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_RECURSIVE_1ST_( \
- /* no function type and default specified (EMPTY) */ \
- BOOST_PP_EMPTY, 0 /* no defaults specified */, name)
-
-// PUBLIC //
-
-// name: [(function_type)] [(default_count)] [inline] [recursive] name
-#define BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS(name) \
- BOOST_PP_IIF(BOOST_PP_IS_UNARY(name), \
- BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_FTYPE_YES_ \
- , \
- BOOST_LOCAL_FUNCTION_AUX_NAME_TRAITS_FTYPE_NO_ \
- )(name)
-
-// Expand to `[function_type]`.
-#define BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS_FUNCTION_TYPE(name_traits) \
- BOOST_PP_TUPLE_ELEM(5, 0, name_traits)(/* expand empty */)
-
-// Expand to 0, 1, 2, ... (0 if not specified).
-#define BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS_DEFAULTS(name_traits) \
- BOOST_PP_TUPLE_ELEM(5, 1, name_traits)
-
-// Expand to 1 iff function was specified recursive.
-#define BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS_IS_RECURSIVE(name_traits) \
- BOOST_PP_TUPLE_ELEM(5, 2, name_traits)
-
-// Expand to 1 iff function was specified inline.
-#define BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS_IS_INLINE(name_traits) \
- BOOST_PP_TUPLE_ELEM(5, 3, name_traits)
-
-// Expand to (unqualified) function name.
-#define BOOST_LOCAL_FUNCTION_AUX_PP_NAME_TRAITS_FUNCTION_NAME(name_traits) \
- BOOST_PP_TUPLE_ELEM(5, 4, name_traits)
-
-#endif // #include guard
-
Modified: trunk/libs/local_function/test/add_typed.cpp
==============================================================================
--- trunk/libs/local_function/test/add_typed.cpp (original)
+++ trunk/libs/local_function/test/add_typed.cpp 2012-04-11 13:14:00 EDT (Wed, 11 Apr 2012)
@@ -16,15 +16,15 @@
#include <algorithm>
//[add_typed
-struct adder { // No type-of used (or registration needed) because...
+struct adder {
adder(void) : sum_(0) {}
int sum(const std::vector<int>& nums, const int& factor = 10) {
- // ...explicitly specify bound variable types, return type, and ...
+ // Explicitly specify bound variable and return types (no type-of).
BOOST_LOCAL_FUNCTION(const bind(const int&) factor,
bind(adder*) this_, int num, return void) {
this_->sum_ += factor * num;
- } BOOST_LOCAL_FUNCTION_NAME((void (int)) add) // ...function type.
+ } BOOST_LOCAL_FUNCTION_NAME(add)
std::for_each(nums.begin(), nums.end(), add);
return sum_;
Modified: trunk/libs/local_function/test/add_typed_seq.cpp
==============================================================================
--- trunk/libs/local_function/test/add_typed_seq.cpp (original)
+++ trunk/libs/local_function/test/add_typed_seq.cpp 2012-04-11 13:14:00 EDT (Wed, 11 Apr 2012)
@@ -17,7 +17,7 @@
BOOST_LOCAL_FUNCTION( (const bind(const int&) factor)
(bind(adder*) this_) (int num) (return void) ) {
this_->sum_ += factor * num;
- } BOOST_LOCAL_FUNCTION_NAME((void (int)) add)
+ } BOOST_LOCAL_FUNCTION_NAME(add)
std::for_each(nums.begin(), nums.end(), add);
return sum_;
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