]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/local_function/aux_/macro/name.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / local_function / aux_ / macro / name.hpp
1
2 // Copyright (C) 2009-2012 Lorenzo Caminiti
3 // Distributed under the Boost Software License, Version 1.0
4 // (see accompanying file LICENSE_1_0.txt or a copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 // Home at http://www.boost.org/libs/local_function
7
8 #ifndef BOOST_LOCAL_FUNCTION_AUX_NAME_HPP_
9 #define BOOST_LOCAL_FUNCTION_AUX_NAME_HPP_
10
11 #include <boost/local_function/config.hpp>
12 #include <boost/local_function/aux_/macro/decl.hpp>
13 #include <boost/local_function/aux_/macro/code_/functor.hpp>
14 #include <boost/local_function/detail/preprocessor/keyword/recursive.hpp>
15 #include <boost/local_function/detail/preprocessor/keyword/inline.hpp>
16 #include <boost/local_function/aux_/function.hpp>
17 #include <boost/local_function/aux_/symbol.hpp>
18 #include <boost/preprocessor/control/iif.hpp>
19 #include <boost/preprocessor/control/expr_iif.hpp>
20 #include <boost/preprocessor/logical/bitor.hpp>
21 #include <boost/preprocessor/tuple/eat.hpp>
22
23 // PRIVATE //
24
25 #define BOOST_LOCAL_FUNCTION_AUX_NAME_LOCAL_TYPE_(local_function_name) \
26 BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (local_type)(local_function_name) )
27
28 #define BOOST_LOCAL_FUNCTION_AUX_NAME_INIT_RECURSION_FUNC_ \
29 BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (init_recursion) )
30
31 #define BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_FUNC_( \
32 is_recursive, local_function_name) \
33 BOOST_PP_IIF(is_recursive, \
34 local_function_name \
35 , \
36 BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (nonrecursive_local_function_name) ) \
37 )
38
39 #define BOOST_LOCAL_FUNCTION_AUX_NAME_END_LOCAL_FUNCTOR_(typename01, \
40 local_function_name, is_recursive, \
41 local_functor_name, nonlocal_functor_name) \
42 /* FUNCTION macro expanded to: typedef class functor ## __LINE__ { ... */ \
43 BOOST_PP_EXPR_IIF(is_recursive, \
44 /* member var with function name for recursive calls; it cannot be */ \
45 /* `const` because it is init after construction (because */ \
46 /* constructor doesn't know local function name) */ \
47 /* run-time: even when optimizing, recursive calls cannot be */ \
48 /* optimized (i.e., they must be via the non-local functor) */ \
49 /* because this cannot be a mem ref because its name is not known */ \
50 /* by the constructor so it cannot be set by the mem init list */ \
51 private: \
52 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_TYPE \
53 BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_FUNC_(is_recursive, \
54 local_function_name); \
55 /* run-time: the `init_recursion()` function cannot be called */ \
56 /* by the constructor to allow for compiler optimization */ \
57 /* (inlining) so it must be public to be called (see below) */ \
58 public: \
59 inline void BOOST_LOCAL_FUNCTION_AUX_NAME_INIT_RECURSION_FUNC_( \
60 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_TYPE& functor) { \
61 local_function_name = functor; \
62 } \
63 ) \
64 } BOOST_LOCAL_FUNCTION_AUX_NAME_LOCAL_TYPE_(local_function_name); \
65 /* local functor can be passed as tparam only on C++11 (faster) */ \
66 BOOST_LOCAL_FUNCTION_AUX_NAME_LOCAL_TYPE_(local_function_name) \
67 local_functor_name(BOOST_LOCAL_FUNCTION_AUX_DECL_ARGS_VAR.value); \
68 /* non-local functor can always be passed as tparam (but slower) */ \
69 BOOST_PP_EXPR_IIF(typename01, typename) \
70 BOOST_LOCAL_FUNCTION_AUX_NAME_LOCAL_TYPE_(local_function_name):: \
71 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_TYPE \
72 nonlocal_functor_name; /* functor variable */ \
73 /* the order of the following 2 function calls cannot be changed */ \
74 /* because init_recursion uses the local_functor so the local_functor */ \
75 /* must be init first */ \
76 local_functor_name.BOOST_LOCAL_FUNCTION_AUX_FUNCTION_INIT_CALL_FUNC( \
77 &local_functor_name, nonlocal_functor_name); \
78 BOOST_PP_EXPR_IIF(is_recursive, \
79 /* init recursion causes MSVC to not optimize local function not */ \
80 /* even when local functor is used as template parameter so no */ \
81 /* recursion unless all inlining optimizations are specified off */ \
82 local_functor_name.BOOST_LOCAL_FUNCTION_AUX_NAME_INIT_RECURSION_FUNC_( \
83 nonlocal_functor_name); \
84 )
85
86 #define BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_(local_function_name) \
87 BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (local_function_name) )
88
89 // This can always be passed as a template parameters (on all compilers).
90 // However, it is slower because it cannot be inlined.
91 // Passed at tparam: Yes (on all C++). Inlineable: No. Recursive: No.
92 #define BOOST_LOCAL_FUNCTION_AUX_NAME_(typename01, local_function_name) \
93 BOOST_LOCAL_FUNCTION_AUX_NAME_END_LOCAL_FUNCTOR_(typename01, \
94 local_function_name, \
95 /* local function is not recursive (because recursion and its */ \
96 /* initialization cannot be inlined even on C++11, */ \
97 /* so this allows optimization at least on C++11) */ \
98 0 /* not recursive */ , \
99 /* local functor */ \
100 BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_(local_function_name), \
101 /* local function declared as non-local functor -- but it can */ \
102 /* be inlined only by C++11 and it cannot be recursive */ \
103 local_function_name)
104
105 // This is faster on some compilers but not all (e.g., it is faster on GCC
106 // because its optimization inlines it but not on MSVC). However, it cannot be
107 // passed as a template parameter on non C++11 compilers.
108 // Passed at tparam: Only on C++11. Inlineable: Yes. Recursive: No.
109 #define BOOST_LOCAL_FUNCTION_AUX_NAME_INLINE_(typename01, local_function_name) \
110 BOOST_LOCAL_FUNCTION_AUX_NAME_END_LOCAL_FUNCTOR_(typename01, \
111 local_function_name, \
112 /* inlined local function is never recursive (because recursion */ \
113 /* and its initialization cannot be inlined)*/ \
114 0 /* not recursive */ , \
115 /* inlined local function declared as local functor (maybe */ \
116 /* inlined even by non C++11 -- but it can be passed as */ \
117 /* template parameter only on C++11 */ \
118 local_function_name, \
119 /* non-local functor */ \
120 BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_(local_function_name))
121
122 // This is slower on all compilers (C++11 and non) because recursion and its
123 // initialization can never be inlined.
124 // Passed at tparam: Yes. Inlineable: No. Recursive: Yes.
125 #define BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_( \
126 typename01, local_function_name) \
127 BOOST_LOCAL_FUNCTION_AUX_NAME_END_LOCAL_FUNCTOR_(typename01, \
128 local_function_name, \
129 /* recursive local function -- but it cannot be inlined */ \
130 1 /* recursive */ , \
131 /* local functor */ \
132 BOOST_LOCAL_FUNCTION_AUX_NAME_FUNCTOR_(local_function_name), \
133 /* local function declared as non-local functor -- but it can */ \
134 /* be inlined only by C++11 */ \
135 local_function_name)
136
137 // Inlined local functions are specified by `..._NAME(inline name)`.
138 // They have more chances to be inlined for faster run-times by some compilers
139 // (for example by GCC but not by MSVC). C++11 compilers can always inline
140 // local functions even if they are not explicitly specified inline.
141 #define BOOST_LOCAL_FUNCTION_AUX_NAME_PARSE_INLINE_( \
142 typename01, qualified_name) \
143 BOOST_PP_IIF(BOOST_PP_BITOR( \
144 BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS, \
145 BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_INLINE_FRONT( \
146 qualified_name)), \
147 /* on C++11 always use inlining because compilers might optimize */ \
148 /* it to be faster and it can also be passed as tparam */ \
149 BOOST_LOCAL_FUNCTION_AUX_NAME_INLINE_ \
150 , \
151 /* on non C++11 don't use liniling unless explicitly specified by */ \
152 /* programmers `inline name` the inlined local function cannot be */ \
153 /* passed as tparam */ \
154 BOOST_LOCAL_FUNCTION_AUX_NAME_ \
155 )(typename01, BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_REMOVE_FRONT( \
156 qualified_name))
157
158 // Expand to 1 iff `recursive name` or `recursive inline name` or
159 // `inline recursive name`.
160 #define BOOST_LOCAL_FUNCTION_AUX_NAME_IS_RECURSIVE_(qualified_name) \
161 BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_RECURSIVE_FRONT( \
162 BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_REMOVE_FRONT( \
163 qualified_name \
164 ))
165
166 // Revmoes `recursive`, `inline recursive`, and `recursive inline` from front.
167 #define BOOST_LOCAL_FUNCTION_AUX_NAME_REMOVE_RECURSIVE_AND_INLINE_( \
168 qualified_name) \
169 BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RECURSIVE_REMOVE_FRONT( \
170 BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_INLINE_REMOVE_FRONT( \
171 BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RECURSIVE_REMOVE_FRONT( \
172 qualified_name \
173 )))
174
175 #define BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_REMOVE_(qualified_name) \
176 BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_AUX_NAME_IS_RECURSIVE_(qualified_name), \
177 BOOST_LOCAL_FUNCTION_AUX_NAME_REMOVE_RECURSIVE_AND_INLINE_ \
178 , \
179 qualified_name /* might be `name` or `inline name` */ \
180 BOOST_PP_TUPLE_EAT(1) \
181 )(qualified_name)
182
183 // Recursive local function are specified by `..._NAME(recursive name)`.
184 // They can never be inlined for faster run-time (not even by C++11 compilers).
185 #define BOOST_LOCAL_FUNCTION_AUX_NAME_PARSE_RECURSIVE_( \
186 typename01, qualified_name) \
187 BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_AUX_NAME_IS_RECURSIVE_(qualified_name), \
188 /* recursion can never be inlined (not even on C++11) */ \
189 BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_ \
190 , \
191 BOOST_LOCAL_FUNCTION_AUX_NAME_PARSE_INLINE_ \
192 )(typename01, \
193 BOOST_LOCAL_FUNCTION_AUX_NAME_RECURSIVE_REMOVE_(qualified_name))
194
195 // PUBLIC //
196
197 #define BOOST_LOCAL_FUNCTION_AUX_NAME(typename01, qualified_name) \
198 BOOST_LOCAL_FUNCTION_AUX_NAME_PARSE_RECURSIVE_(typename01, qualified_name)
199
200 #endif // #include guard
201