Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:54:14

0001 
0002 // Copyright (C) 2009-2012 Lorenzo Caminiti
0003 // Distributed under the Boost Software License, Version 1.0
0004 // (see accompanying file LICENSE_1_0.txt or a copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
0006 // Home at http://www.boost.org/libs/local_function
0007 
0008 #ifndef BOOST_LOCAL_FUNCTION_AUX_NAME_HPP_
0009 #define BOOST_LOCAL_FUNCTION_AUX_NAME_HPP_
0010 
0011 #include <boost/local_function/config.hpp>
0012 #include <boost/local_function/aux_/macro/decl.hpp>
0013 #include <boost/local_function/aux_/macro/code_/functor.hpp>
0014 #include <boost/local_function/detail/preprocessor/keyword/recursive.hpp>
0015 #include <boost/local_function/detail/preprocessor/keyword/inline.hpp>
0016 #include <boost/local_function/aux_/function.hpp>
0017 #include <boost/local_function/aux_/symbol.hpp>
0018 #include <boost/preprocessor/control/iif.hpp>
0019 #include <boost/preprocessor/control/expr_iif.hpp>
0020 #include <boost/preprocessor/logical/bitor.hpp>
0021 #include <boost/preprocessor/tuple/eat.hpp>
0022 
0023 // PRIVATE //
0024 
0025 #define BOOST_LOCAL_FUNCTION_AUX_NAME_LOCAL_TYPE_(local_function_name) \
0026     BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (local_type)(local_function_name) )
0027 
0028 #define BOOST_LOCAL_FUNCTION_AUX_NAME_INIT_RECURSION_FUNC_ \
0029     BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (init_recursion) )
0030 
0031 #define BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_FUNC_( \
0032         is_recursive, local_function_name) \
0033     BOOST_PP_IIF(is_recursive, \
0034         local_function_name \
0035     , \
0036         BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (nonrecursive_local_function_name) ) \
0037     )
0038 
0039 #define BOOST_LOCAL_FUNCTION_AUX_NAME_END_LOCAL_FUNCTOR_(typename01, \
0040         local_function_name, is_recursive, \
0041         local_functor_name, nonlocal_functor_name) \
0042     /* FUNCTION macro expanded to: typedef class functor ## __LINE__ { ... */ \
0043     BOOST_PP_EXPR_IIF(is_recursive, \
0044         /* member var with function name for recursive calls; it cannot be */ \
0045         /* `const` because it is init after construction (because */ \
0046         /* constructor doesn't know local function name) */ \
0047         /* run-time: even when optimizing, recursive calls cannot be */ \
0048         /* optimized (i.e., they must be via the non-local functor) */ \
0049         /* because this cannot be a mem ref because its name is not known */ \
0050         /* by the constructor so it cannot be set by the mem init list */ \
0051     private: \
0052         BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_TYPE \
0053                 BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_FUNC_(is_recursive, \
0054                         local_function_name); \
0055         /* run-time: the `init_recursion()` function cannot be called */ \
0056         /* by the constructor to allow for compiler optimization */ \
0057         /* (inlining) so it must be public to be called (see below) */ \
0058     public: \
0059         inline void BOOST_LOCAL_FUNCTION_AUX_NAME_INIT_RECURSION_FUNC_( \
0060                 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_TYPE& functor) { \
0061             local_function_name = functor; \
0062         } \
0063     ) \
0064     } BOOST_LOCAL_FUNCTION_AUX_NAME_LOCAL_TYPE_(local_function_name); \
0065     /* local functor can be passed as tparam only on C++11 (faster) */ \
0066     BOOST_LOCAL_FUNCTION_AUX_NAME_LOCAL_TYPE_(local_function_name) \
0067             local_functor_name(BOOST_LOCAL_FUNCTION_AUX_DECL_ARGS_VAR.value); \
0068     /* non-local functor can always be passed as tparam (but slower) */ \
0069     BOOST_PP_EXPR_IIF(typename01, typename) \
0070     BOOST_LOCAL_FUNCTION_AUX_NAME_LOCAL_TYPE_(local_function_name):: \
0071             BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_TYPE \
0072             nonlocal_functor_name; /* functor variable */ \
0073     /* the order of the following 2 function calls cannot be changed */ \
0074     /* because init_recursion uses the local_functor so the local_functor */ \
0075     /* must be init first */ \
0076     local_functor_name.BOOST_LOCAL_FUNCTION_AUX_FUNCTION_INIT_CALL_FUNC( \
0077             &local_functor_name, nonlocal_functor_name); \
0078     BOOST_PP_EXPR_IIF(is_recursive, \
0079         /* init recursion causes MSVC to not optimize local function not */ \
0080         /* even when local functor is used as template parameter so no */ \
0081         /* recursion unless all inlining optimizations are specified off */ \
0082         local_functor_name.BOOST_LOCAL_FUNCTION_AUX_NAME_INIT_RECURSION_FUNC_( \
0083                 nonlocal_functor_name); \
0084     )
0085 
0086 #define BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_(local_function_name) \
0087     BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (local_function_name) )
0088 
0089 // This can always be passed as a template parameters (on all compilers).
0090 // However, it is slower because it cannot be inlined.
0091 // Passed at tparam: Yes (on all C++). Inlineable: No. Recursive: No.
0092 #define BOOST_LOCAL_FUNCTION_AUX_NAME_(typename01, local_function_name) \
0093     BOOST_LOCAL_FUNCTION_AUX_NAME_END_LOCAL_FUNCTOR_(typename01, \
0094             local_function_name, \
0095             /* local function is not recursive (because recursion and its */ \
0096             /* initialization cannot be inlined even on C++11, */ \
0097             /* so this allows optimization at least on C++11) */ \
0098             0 /* not recursive */ , \
0099             /* local functor */ \
0100             BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_(local_function_name), \
0101             /* local function declared as non-local functor -- but it can */ \
0102             /* be inlined only by C++11 and it cannot be recursive */ \
0103             local_function_name)
0104 
0105 // This is faster on some compilers but not all (e.g., it is faster on GCC
0106 // because its optimization inlines it but not on MSVC). However, it cannot be
0107 // passed as a template parameter on non C++11 compilers.
0108 // Passed at tparam: Only on C++11. Inlineable: Yes. Recursive: No.
0109 #define BOOST_LOCAL_FUNCTION_AUX_NAME_INLINE_(typename01, local_function_name) \
0110     BOOST_LOCAL_FUNCTION_AUX_NAME_END_LOCAL_FUNCTOR_(typename01, \
0111             local_function_name, \
0112             /* inlined local function is never recursive (because recursion */ \
0113             /* and its initialization cannot be inlined)*/ \
0114             0 /* not recursive */ , \
0115             /* inlined local function declared as local functor (maybe */ \
0116             /* inlined even by non C++11 -- but it can be passed as */ \
0117             /* template parameter only on C++11 */ \
0118             local_function_name, \
0119             /* non-local functor */ \
0120             BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_(local_function_name))
0121 
0122 // This is slower on all compilers (C++11 and non) because recursion and its
0123 // initialization can never be inlined.
0124 // Passed at tparam: Yes. Inlineable: No. Recursive: Yes.
0125 #define BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_( \
0126         typename01, local_function_name) \
0127     BOOST_LOCAL_FUNCTION_AUX_NAME_END_LOCAL_FUNCTOR_(typename01, \
0128             local_function_name, \
0129             /* recursive local function -- but it cannot be inlined */ \
0130             1 /* recursive */ , \
0131             /* local functor */ \
0132             BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_(local_function_name), \
0133             /* local function declared as non-local functor -- but it can */ \
0134             /* be inlined only by C++11 */ \
0135             local_function_name)
0136 
0137 // Inlined local functions are specified by `..._NAME(inline name)`.
0138 // They have more chances to be inlined for faster run-times by some compilers
0139 // (for example by GCC but not by MSVC). C++11 compilers can always inline
0140 // local functions even if they are not explicitly specified inline.
0141 #define BOOST_LOCAL_FUNCTION_AUX_NAME_PARSE_INLINE_( \
0142         typename01, qualified_name) \
0143     BOOST_PP_IIF(BOOST_PP_BITOR( \
0144             BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS, \
0145             BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_INLINE_FRONT( \
0146                     qualified_name)), \
0147         /* on C++11 always use inlining because compilers might optimize */ \
0148         /* it to be faster and it can also be passed as tparam */ \
0149         BOOST_LOCAL_FUNCTION_AUX_NAME_INLINE_ \
0150     , \
0151         /* on non C++11 don't use liniling unless explicitly specified by */ \
0152         /* programmers `inline name` the inlined local function cannot be */ \
0153         /* passed as tparam */ \
0154         BOOST_LOCAL_FUNCTION_AUX_NAME_ \
0155     )(typename01, BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_REMOVE_FRONT( \
0156             qualified_name))
0157 
0158 // Expand to 1 iff `recursive name` or `recursive inline name` or
0159 // `inline recursive name`.
0160 #define BOOST_LOCAL_FUNCTION_AUX_NAME_IS_RECURSIVE_(qualified_name) \
0161     BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_RECURSIVE_FRONT( \
0162     BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_REMOVE_FRONT( \
0163         qualified_name \
0164     ))
0165 
0166 // Revmoes `recursive`, `inline recursive`, and `recursive inline` from front.
0167 #define BOOST_LOCAL_FUNCTION_AUX_NAME_REMOVE_RECURSIVE_AND_INLINE_( \
0168         qualified_name) \
0169     BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RECURSIVE_REMOVE_FRONT( \
0170     BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_REMOVE_FRONT( \
0171     BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RECURSIVE_REMOVE_FRONT( \
0172         qualified_name \
0173     )))
0174 
0175 #define BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_REMOVE_(qualified_name) \
0176     BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_AUX_NAME_IS_RECURSIVE_(qualified_name), \
0177         BOOST_LOCAL_FUNCTION_AUX_NAME_REMOVE_RECURSIVE_AND_INLINE_ \
0178     , \
0179         qualified_name /* might be `name` or `inline name` */ \
0180         BOOST_PP_TUPLE_EAT(1) \
0181     )(qualified_name)
0182 
0183 // Recursive local function are specified by `..._NAME(recursive name)`. 
0184 // They can never be inlined for faster run-time (not even by C++11 compilers).
0185 #define BOOST_LOCAL_FUNCTION_AUX_NAME_PARSE_RECURSIVE_( \
0186         typename01, qualified_name) \
0187     BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_AUX_NAME_IS_RECURSIVE_(qualified_name), \
0188         /* recursion can never be inlined (not even on C++11) */ \
0189         BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_ \
0190     , \
0191         BOOST_LOCAL_FUNCTION_AUX_NAME_PARSE_INLINE_ \
0192     )(typename01, \
0193             BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_REMOVE_(qualified_name))
0194 
0195 // PUBLIC //
0196 
0197 #define BOOST_LOCAL_FUNCTION_AUX_NAME(typename01, qualified_name) \
0198     BOOST_LOCAL_FUNCTION_AUX_NAME_PARSE_RECURSIVE_(typename01, qualified_name)
0199 
0200 #endif // #include guard
0201