]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/local_function/include/boost/local_function/aux_/macro/code_/functor.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / local_function / include / boost / local_function / aux_ / macro / code_ / functor.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_CODE_FUNCTOR_HPP_
9 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_HPP_
10
11 #include <boost/local_function/config.hpp>
12 #include <boost/local_function/aux_/symbol.hpp>
13 #include <boost/local_function/aux_/function.hpp>
14 #include <boost/local_function/aux_/add_pointed_const.hpp>
15 #include <boost/local_function/aux_/member.hpp>
16 #include <boost/local_function/aux_/nobind.hpp>
17 #include <boost/local_function/aux_/macro/decl.hpp>
18 #include <boost/local_function/aux_/macro/typeof.hpp>
19 #include <boost/local_function/aux_/macro/code_/result.hpp>
20 #include <boost/local_function/aux_/macro/code_/bind.hpp>
21 #include <boost/local_function/aux_/preprocessor/traits/decl_params.hpp>
22 #include <boost/local_function/aux_/preprocessor/traits/decl_binds.hpp>
23 #include <boost/local_function/aux_/preprocessor/traits/decl_const_binds.hpp>
24 #include <boost/local_function/detail/preprocessor/keyword/auto.hpp>
25 #include <boost/local_function/detail/preprocessor/keyword/register.hpp>
26 #include <boost/local_function/detail/preprocessor/keyword/thisunderscore.hpp>
27 #include <boost/utility/identity_type.hpp>
28 #include <boost/scope_exit.hpp>
29 #include <boost/type_traits/add_const.hpp>
30 #include <boost/preprocessor/cat.hpp>
31 #include <boost/preprocessor/punctuation/comma_if.hpp>
32 #include <boost/preprocessor/control/expr_iif.hpp>
33 #include <boost/preprocessor/control/iif.hpp>
34 #include <boost/preprocessor/facilities/expand.hpp>
35 #include <boost/preprocessor/facilities/is_empty.hpp>
36 #include <boost/preprocessor/facilities/empty.hpp>
37 #include <boost/preprocessor/facilities/identity.hpp>
38 #include <boost/preprocessor/repetition/enum.hpp>
39 #include <boost/preprocessor/repetition/repeat.hpp>
40 #include <boost/preprocessor/arithmetic/inc.hpp>
41 #include <boost/preprocessor/arithmetic/sub.hpp>
42 #include <boost/preprocessor/arithmetic/add.hpp>
43 #include <boost/preprocessor/logical/bitor.hpp>
44 #include <boost/preprocessor/logical/bitand.hpp>
45 #include <boost/preprocessor/logical/compl.hpp>
46 #include <boost/preprocessor/tuple/elem.hpp>
47 #include <boost/preprocessor/tuple/eat.hpp>
48 #include <boost/preprocessor/tuple/rem.hpp>
49 #include <boost/preprocessor/list/adt.hpp>
50 #include <boost/preprocessor/list/size.hpp>
51 #include <boost/preprocessor/list/for_each_i.hpp>
52 #include <boost/preprocessor/list/first_n.hpp>
53
54 // PRIVATE //
55
56 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CLASS_TYPE_(id) \
57 BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (functor)(id) )
58
59 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_F_TYPE_ \
60 BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (function_type) )
61
62 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BODY_FUNC_ \
63 BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (body) )
64
65 // Unbind parameters.
66
67 // i: 1 for 1st param, 2 for 2nd, ... (start from 1 not 0).
68 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_NAME_(i) \
69 /* this must be a generic parameter name because type and name */ \
70 /* are not separate tokens in the macro syntax so name is not available */ \
71 /* separately from its type */ \
72 BOOST_PP_CAT(arg, i)
73
74 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_NAME_ENUM_( \
75 r, unused, i, param_traits) \
76 BOOST_PP_COMMA_IF(i) /* enumeration commas */ \
77 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_NAME_(BOOST_PP_INC(i))
78
79 // i: 1 for 1st param, 2 for 2nd, ... (start from 1 not 0).
80 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_TYPE_(typename01, i) \
81 /* the parameter type must be accessed using function traits from */ \
82 /* function type because it is not available to the macro syntax */ \
83 /* separately from the parameter name */ \
84 BOOST_PP_EXPR_IIF(typename01, typename) \
85 ::boost::function_traits< \
86 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_F_TYPE_ \
87 >::BOOST_PP_CAT(BOOST_PP_CAT(arg, i), _type) \
88
89 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_ARG_TYPEDEF_( \
90 r, typename01, i, param_traits) \
91 typedef \
92 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_TYPE_(typename01, \
93 BOOST_PP_INC(i)) \
94 /* name must follow Boost.FunctionTraits arg1_type, arg2_type, ... */ \
95 BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(i)), _type) \
96 ;
97
98 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_DECL_( \
99 r, typename01, i, param_traits) \
100 BOOST_PP_EXPR_IIF(typename01, typename) \
101 ::boost::call_traits< \
102 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_TYPE_(typename01, \
103 BOOST_PP_INC(i)) \
104 >::param_type \
105 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_NAME_(BOOST_PP_INC(i))
106
107 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_DECL_ENUM_( \
108 r, typename01, i, param_traits) \
109 BOOST_PP_COMMA_IF(i) \
110 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_DECL_(r, typename01, i, \
111 param_traits)
112
113 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_PARAM_ARG_DECL_( \
114 r, typename01, i, param_traits) \
115 , BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_DECL_(r, typename01, i, \
116 param_traits)
117
118 // Precondition: !EMPTY(DEFAULT(param_traits))
119 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_DEFAULT_ASSIGNMENT_( \
120 param_traits) \
121 = BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_DEFAULT_REMOVE_FRONT( \
122 BOOST_LOCAL_FUNCTION_AUX_PP_PARAM_TRAITS_DEFAULT(param_traits))
123
124 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_DECL_ENUM_( \
125 r, default01, i, param_traits) \
126 BOOST_PP_COMMA_IF(i) \
127 BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_AUTO_REMOVE_BACK( \
128 BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_REGISTER_REMOVE_BACK( \
129 BOOST_LOCAL_FUNCTION_AUX_PP_PARAM_TRAITS_DECL(param_traits) \
130 )) \
131 BOOST_PP_IIF(BOOST_PP_COMPL(default01), \
132 BOOST_PP_TUPLE_EAT(1) /* without default */ \
133 , BOOST_PP_IIF(BOOST_PP_IS_EMPTY( \
134 BOOST_LOCAL_FUNCTION_AUX_PP_PARAM_TRAITS_DEFAULT(param_traits)), \
135 BOOST_PP_TUPLE_EAT(1) /* has no default */ \
136 , /* else, with default and has default */ \
137 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_DEFAULT_ASSIGNMENT_ \
138 ))(param_traits)
139
140 // Bound parameters.
141
142 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAMS_ \
143 bind_params /* constructor void* param */
144
145 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_VAR_(i) \
146 /* named `bind0`, `bind1`, ... */ \
147 BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (bind)(i) )
148
149 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_MEMBER_THIS_ \
150 BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (bind_this) )
151
152 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_STATIC_BIND_MEMBER_THIS_( \
153 id) \
154 , static_cast< BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CLASS_TYPE_(id)* >( \
155 object)->BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_MEMBER_THIS_
156
157 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_TYPE_( \
158 id, typename01, offset, i, bind_var_without_type) \
159 BOOST_PP_EXPR_IIF(typename01, typename) \
160 BOOST_SCOPE_EXIT_DETAIL_PARAMS_T(id):: \
161 BOOST_SCOPE_EXIT_DETAIL_PARAM_T(id, BOOST_PP_ADD(i, offset), \
162 bind_var_without_type) \
163
164 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_MEMBER_BIND_ENUM_( \
165 r, offset, i, bind_traits) \
166 BOOST_PP_COMMA_IF(i) \
167 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_VAR_( \
168 BOOST_PP_ADD(offset, i))
169
170 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_DECL_TYPE_( \
171 r, id_typename_offset_const, i, bind_var_without_type) \
172 /* IMPORTANT: here can't use `PP_KEYWORD_IS_THISUNDERSCORE_FRONT()` */ \
173 /* because some `param_name` might start with non-alphanumeric symbol */ \
174 /* `&` (but that is never the case for `this`) */ \
175 BOOST_PP_IIF(BOOST_PP_COMPL(BOOST_PP_TUPLE_ELEM(4, 3, \
176 id_typename_offset_const)), \
177 BOOST_PP_EMPTY \
178 , BOOST_PP_IIF( \
179 BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_THISUNDERSCORE_BACK( \
180 bind_var_without_type), \
181 /* pointed obj const */ \
182 BOOST_PP_EXPR_IIF(BOOST_PP_TUPLE_ELEM(4, 1, id_typename_offset_const), \
183 typename \
184 ) \
185 BOOST_PP_IDENTITY( ::boost::local_function::aux::add_pointed_const< ) \
186 , \
187 BOOST_PP_EXPR_IIF(BOOST_PP_TUPLE_ELEM(4, 1, id_typename_offset_const), \
188 typename \
189 ) \
190 BOOST_PP_IDENTITY( ::boost::add_const< ) /* outer type const */ \
191 ))() \
192 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_TYPE_( \
193 BOOST_PP_TUPLE_ELEM(4, 0, id_typename_offset_const), \
194 BOOST_PP_TUPLE_ELEM(4, 1, id_typename_offset_const), \
195 BOOST_PP_TUPLE_ELEM(4, 2, id_typename_offset_const), \
196 i, bind_var_without_type) \
197 BOOST_PP_EXPR_IIF(BOOST_PP_TUPLE_ELEM(4, 3, id_typename_offset_const), \
198 >::type \
199 )
200
201 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_DECL_( \
202 r, id_typename_offset_const, i, bind_var_without_type) \
203 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_DECL_TYPE_( \
204 r, id_typename_offset_const, i, bind_var_without_type) \
205 BOOST_PP_IIF( \
206 BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_THISUNDERSCORE_BACK( \
207 BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_VAR_WITHOUT_TYPE( \
208 bind_var_without_type)), \
209 this_ BOOST_PP_TUPLE_EAT(1) \
210 , \
211 BOOST_PP_TUPLE_REM(1) \
212 )(bind_var_without_type)
213
214 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_MAYBECONST_BIND_TYPE_( \
215 r, id_typename_offset_const, i, bind_traits) \
216 , BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_DECL_TYPE_( \
217 r, id_typename_offset_const, i, \
218 BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_VAR_WITHOUT_TYPE( \
219 bind_traits))
220
221 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_PARAM_( \
222 offset, i) \
223 BOOST_PP_CAT(bind, BOOST_PP_ADD(offset, i))
224
225 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_PARAM_ENUM_( \
226 r, offset, i, bind_traits) \
227 BOOST_PP_COMMA_IF(i) \
228 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_PARAM_(offset, i)
229
230 #define \
231 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_MAYBECONST_BIND_PARAM_DECL_( \
232 r, id_typename_offset_const, i, bind_traits) \
233 , BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_DECL_TYPE_( \
234 r, id_typename_offset_const, i, \
235 BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_VAR_WITHOUT_TYPE( \
236 bind_traits)) & \
237 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_PARAM_( \
238 BOOST_PP_TUPLE_ELEM(4, 2, id_typename_offset_const), i)
239
240 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_BIND_THIS_TYPE_( \
241 id, typename01) \
242 , BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPE(id, typename01)
243
244 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_THIS_PARAM_ \
245 bind_this
246
247 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_BIND_THIS_PARAM_DECL_( \
248 id, typename01) \
249 , BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPE(id, typename01) & \
250 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_THIS_PARAM_
251
252 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_NOBIND_(z, n, unused) \
253 , ::boost::local_function::aux::nobind
254
255 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_NOBIND_TYPE_(z, n, unused) \
256 , ::boost::local_function::aux::nobind_t
257
258 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_NOBIND_PARAM_DECL_( \
259 z, n, unused) \
260 , ::boost::local_function::aux::nobind_t & \
261 /* param name not needed here because no bind param not used */
262
263 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_DECL_ENUM_( \
264 r, id_typename_offset_const, i, bind_traits) \
265 BOOST_PP_COMMA_IF(i) /* enumeration commas */ \
266 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_DECL_( \
267 r, id_typename_offset_const, i, \
268 BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_VAR_WITHOUT_TYPE( \
269 bind_traits))
270
271 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_DECL_( \
272 r, id_typename_offset_const, i, bind_traits) \
273 BOOST_PP_EXPR_IIF(BOOST_PP_TUPLE_ELEM(4, 1, id_typename_offset_const), \
274 typename \
275 ) \
276 ::boost::local_function::aux::member_type< \
277 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_DECL_TYPE_( \
278 r, id_typename_offset_const, i, bind_var_without_type) \
279 >::reference \
280 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_VAR_( \
281 BOOST_PP_ADD(i, BOOST_PP_TUPLE_ELEM(4, 2, \
282 id_typename_offset_const))) \
283 ; /* end member variable declaration */
284
285 #define \
286 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_MAYBECONST_STATIC_BIND_MEMBER_( \
287 r, id_typename_offset_const, i, bind_traits) \
288 , static_cast< BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CLASS_TYPE_( \
289 BOOST_PP_TUPLE_ELEM(4, 0, id_typename_offset_const))* >(object)-> \
290 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_VAR_( \
291 BOOST_PP_ADD(i, BOOST_PP_TUPLE_ELEM(4, 2, \
292 id_typename_offset_const)))
293
294 #define \
295 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_INIT_ENUM_( \
296 r, id_offset, i, bind_traits) \
297 BOOST_PP_COMMA_IF(i) \
298 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_VAR_( \
299 BOOST_PP_ADD(i, BOOST_PP_TUPLE_ELEM(2, 1, id_offset))) \
300 ( /* member variable initialization */ \
301 static_cast< \
302 BOOST_SCOPE_EXIT_DETAIL_PARAMS_T( \
303 BOOST_PP_TUPLE_ELEM(2, 0, id_offset))* \
304 >(BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAMS_)-> \
305 BOOST_SCOPE_EXIT_DETAIL_PARAM( \
306 BOOST_PP_TUPLE_ELEM(2, 0, id_offset) \
307 , BOOST_PP_ADD(i, BOOST_PP_TUPLE_ELEM(2, 1, id_offset)) \
308 , BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_VAR_WITHOUT_TYPE( \
309 bind_traits) \
310 ).value \
311 )
312
313 // Typeof type-definitions.
314
315 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_TYPEDEF_( \
316 r, id_typename_offset_const, i, bind_traits) \
317 typedef /* the type with the special typeof name */ \
318 BOOST_LOCAL_FUNCTION_AUX_TYPEOF_TYPE( \
319 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_DECL_( \
320 r, id_typename_offset_const, i, \
321 BOOST_LOCAL_FUNCTION_AUX_PP_BIND_TRAITS_VAR_WITHOUT_TYPE( \
322 bind_traits)) \
323 ) \
324 ; /* end typedef */
325
326 // Expand to the function type `R (A1, ...)`.
327 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_F_( \
328 id, typename01, decl_traits, has_type, function_type) \
329 BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPE(id, typename01) \
330 BOOST_PP_EXPR_IIF(has_type, (function_type) ) \
331 ( \
332 BOOST_PP_LIST_FOR_EACH_I( \
333 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_DECL_ENUM_, \
334 0, /* without defaults */ \
335 BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_PARAMS(decl_traits)) \
336 )
337
338 // Functor call operations.
339
340 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CALL_BODY_(id, typename01, \
341 const_bind_macro, bind_macro, const_bind_this_macro, bind_this_macro, \
342 param_macro, params, \
343 const_binds, has_const_bind_this, binds, has_bind_this) \
344 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BODY_FUNC_( \
345 BOOST_PP_LIST_FOR_EACH_I(const_bind_macro, \
346 0 /* no offset */, const_binds) \
347 /* pass plain binds */ \
348 BOOST_PP_COMMA_IF( \
349 BOOST_PP_BITAND( \
350 BOOST_PP_LIST_IS_CONS(const_binds) \
351 , BOOST_PP_LIST_IS_CONS(binds) \
352 ) \
353 ) \
354 BOOST_PP_LIST_FOR_EACH_I(bind_macro, \
355 /* offset index of # const-binds (could be 0) */ \
356 BOOST_PP_LIST_SIZE(const_binds), binds) \
357 /* pass bind `this` */ \
358 BOOST_PP_COMMA_IF( \
359 BOOST_PP_BITAND( \
360 BOOST_PP_BITOR( \
361 BOOST_PP_LIST_IS_CONS(const_binds) \
362 , BOOST_PP_LIST_IS_CONS(binds) \
363 ) \
364 , BOOST_PP_BITOR(has_const_bind_this, has_bind_this) \
365 ) \
366 ) \
367 BOOST_PP_EXPR_IIF(has_const_bind_this, const_bind_this_macro) \
368 BOOST_PP_EXPR_IIF(has_bind_this, bind_this_macro) \
369 /* pass params */ \
370 BOOST_PP_COMMA_IF( \
371 BOOST_PP_BITAND( \
372 BOOST_PP_BITOR( \
373 BOOST_PP_BITOR( \
374 BOOST_PP_LIST_IS_CONS(const_binds) \
375 , BOOST_PP_LIST_IS_CONS(binds) \
376 ) \
377 , BOOST_PP_BITOR(has_const_bind_this, has_bind_this) \
378 ) \
379 , BOOST_PP_LIST_IS_CONS(params) \
380 ) \
381 ) \
382 BOOST_PP_LIST_FOR_EACH_I(param_macro, ~, params) \
383 )
384
385 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CALL_(z, defaults_n, \
386 id, typename01, decl_traits, params, \
387 const_binds, has_const_bind_this, binds, has_bind_this) \
388 inline BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPE(id, typename01) \
389 operator()( \
390 BOOST_PP_LIST_FOR_EACH_I( \
391 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_DECL_ENUM_, \
392 typename01, params) \
393 ) /* cannot be const because of binds (same as for global fctor) */ { \
394 /* just forward call to member function with local func name */ \
395 return BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CALL_BODY_(id, typename01,\
396 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_MEMBER_BIND_ENUM_, \
397 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_MEMBER_BIND_ENUM_, \
398 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_MEMBER_THIS_, \
399 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_MEMBER_THIS_, \
400 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_NAME_ENUM_, \
401 params, const_binds, has_const_bind_this, binds, \
402 has_bind_this); \
403 }
404
405 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_FUNC_( \
406 z, defaults_n, unused) \
407 BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (call)(defaults_n) )
408
409 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_COMMA_FUNC_ADDR_( \
410 z, defaults_n, unused) \
411 , &BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_FUNC_(z, defaults_n, ~)
412
413 // Precondition: NO_LOCAL_TYPES_AS_TEMPLATE_PARAMS.
414 #define \
415 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_COMMA_BIND_PARAM_DECLS_( \
416 id, typename01, const_binds, has_const_bind_this, binds, has_bind_this)\
417 BOOST_PP_LIST_FOR_EACH_I( \
418 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_MAYBECONST_BIND_PARAM_DECL_, \
419 ( id, typename01, 0 /* no offset */, 1 /* const */ ), const_binds) \
420 BOOST_PP_LIST_FOR_EACH_I( \
421 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_MAYBECONST_BIND_PARAM_DECL_, \
422 /* offset of # of const-binds */ \
423 ( id, typename01, BOOST_PP_LIST_SIZE(const_binds), 0 /* const */ ),\
424 binds) \
425 BOOST_PP_IIF(BOOST_PP_BITOR(has_bind_this, \
426 has_const_bind_this), \
427 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_BIND_THIS_PARAM_DECL_ \
428 , \
429 BOOST_PP_TUPLE_EAT(2) \
430 )(id, typename01) \
431 /* fill with nobind_t (if no local-types as tparams) */ \
432 BOOST_PP_REPEAT(BOOST_PP_SUB(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX, \
433 BOOST_PP_IIF(BOOST_PP_BITOR(has_bind_this, \
434 has_const_bind_this), \
435 BOOST_PP_INC \
436 , \
437 BOOST_PP_TUPLE_REM(1) \
438 )(BOOST_PP_LIST_SIZE(BOOST_PP_LIST_APPEND(const_binds, \
439 binds)))), \
440 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_NOBIND_PARAM_DECL_, ~)
441
442 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_OPERATOR_( \
443 id, typename01, \
444 params, const_binds, has_const_bind_this, binds, has_bind_this) \
445 operator()( \
446 BOOST_PP_LIST_FOR_EACH_I( \
447 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_NAME_ENUM_, ~, \
448 params) \
449 )
450
451 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_BODY_( \
452 id, typename01, \
453 params, const_binds, has_const_bind_this, binds, has_bind_this) \
454 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CALL_BODY_(id, typename01, \
455 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_PARAM_ENUM_, \
456 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_PARAM_ENUM_, \
457 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_THIS_PARAM_, \
458 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_THIS_PARAM_, \
459 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_ARG_NAME_ENUM_, \
460 params, const_binds, has_const_bind_this, binds, has_bind_this)
461
462 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_(z, defaults_n, \
463 id, typename01, decl_traits, params, \
464 const_binds, has_const_bind_this, binds, has_bind_this) \
465 inline static BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPE(id, typename01) \
466 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_FUNC_(z, defaults_n, ~)( \
467 void* object \
468 BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS, \
469 BOOST_PP_TUPLE_EAT(6) \
470 , \
471 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_COMMA_BIND_PARAM_DECLS_ \
472 )(id, typename01, \
473 const_binds, has_const_bind_this, binds, has_bind_this) \
474 BOOST_PP_LIST_FOR_EACH_I( \
475 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_PARAM_ARG_DECL_, \
476 typename01, params) \
477 ) { \
478 /* run-time: casting object to this class type and forward call to */ \
479 /* `operator()` (this performs better than doing multiple casting */ \
480 /* or using a casted object local variable here to call body */ \
481 /* directly from here without passing via `operator()`) */ \
482 /* compliance: passing local class type to `static_cast` is fully */ \
483 /* C++03 compliant because `static_cast` is not a template (even */ \
484 /* if its syntax resembles a function template call) in fact even */ \
485 /* in C is legal to cast to a local struct (using C-style casting) */ \
486 return \
487 static_cast< \
488 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CLASS_TYPE_(id)* \
489 >(object)-> \
490 BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS,\
491 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_OPERATOR_ \
492 , \
493 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_BODY_ \
494 )(id, typename01, params, \
495 const_binds, has_const_bind_this, binds, has_bind_this) \
496 ; \
497 }
498
499 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CALL_FOR_DEFAULTS_(z, defaults_n, \
500 op_id_typename_decl_params_constbinds_hasconstthis_binds_hasthis) \
501 BOOST_PP_EXPAND( \
502 BOOST_PP_TUPLE_ELEM(9, 0, \
503 op_id_typename_decl_params_constbinds_hasconstthis_binds_hasthis) \
504 ( z, defaults_n \
505 , BOOST_PP_TUPLE_ELEM(9, 1, /* id */\
506 op_id_typename_decl_params_constbinds_hasconstthis_binds_hasthis) \
507 , BOOST_PP_TUPLE_ELEM(9, 2, /* typename01 */ \
508 op_id_typename_decl_params_constbinds_hasconstthis_binds_hasthis) \
509 , BOOST_PP_TUPLE_ELEM(9, 3, /* decl_traits */ \
510 op_id_typename_decl_params_constbinds_hasconstthis_binds_hasthis) \
511 , BOOST_PP_LIST_FIRST_N( /* remove last n default params */ \
512 BOOST_PP_SUB(BOOST_PP_LIST_SIZE(BOOST_PP_TUPLE_ELEM(9, 4, \
513 op_id_typename_decl_params_constbinds_hasconstthis_binds_hasthis)),\
514 defaults_n) \
515 , BOOST_PP_TUPLE_ELEM(9, 4, \
516 op_id_typename_decl_params_constbinds_hasconstthis_binds_hasthis) \
517 ) \
518 , BOOST_PP_TUPLE_ELEM(9, 5, /* const_binds */ \
519 op_id_typename_decl_params_constbinds_hasconstthis_binds_hasthis) \
520 , BOOST_PP_TUPLE_ELEM(9, 6, /* has_const_bind_this */ \
521 op_id_typename_decl_params_constbinds_hasconstthis_binds_hasthis) \
522 , BOOST_PP_TUPLE_ELEM(9, 7, /* binds */ \
523 op_id_typename_decl_params_constbinds_hasconstthis_binds_hasthis) \
524 , BOOST_PP_TUPLE_ELEM(9, 8, /* has_bind_this */ \
525 op_id_typename_decl_params_constbinds_hasconstthis_binds_hasthis) \
526 ) /* end `op_macro(...)` */ \
527 ) /* end expand */
528
529 // Functor binds.
530
531 // Precondition: NO_LOCAL_TYPES_AS_TEMPLATE_PARAMS.
532 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_BIND_TYPES_( \
533 id, typename01, const_binds, has_const_bind_this, binds, has_bind_this)\
534 BOOST_PP_LIST_FOR_EACH_I( \
535 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_MAYBECONST_BIND_TYPE_, \
536 ( id, typename01, 0 /* no offset */, 1 /* const */ ), \
537 const_binds) \
538 BOOST_PP_LIST_FOR_EACH_I( \
539 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_MAYBECONST_BIND_TYPE_, \
540 /* offset of # of const-binds */ \
541 ( id, typename01, BOOST_PP_LIST_SIZE(const_binds), 0 /* const */ ),\
542 binds) \
543 BOOST_PP_IIF(BOOST_PP_BITOR(has_bind_this, \
544 has_const_bind_this), \
545 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_BIND_THIS_TYPE_ \
546 , \
547 BOOST_PP_TUPLE_EAT(2) \
548 )(id, typename01) \
549 /* fill with nobind_t (if no local-types as tparams) */ \
550 BOOST_PP_REPEAT(BOOST_PP_SUB(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX, \
551 BOOST_PP_IIF(BOOST_PP_BITOR(has_bind_this, has_const_bind_this), \
552 BOOST_PP_INC \
553 , \
554 BOOST_PP_TUPLE_REM(1) \
555 )(BOOST_PP_LIST_SIZE(BOOST_PP_LIST_APPEND(const_binds, binds)))), \
556 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_NOBIND_TYPE_, ~)
557
558 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_TYPEOF_TYPEDEFS_( \
559 id, typename01, const_binds, has_const_bind_this, binds, has_bind_this)\
560 /* typeof types -- these types are qualified with extra eventual */ \
561 /* const and/or & if their variables are bound by const and/or & */ \
562 /* (this is because it is not possible to strip the eventual & */ \
563 /* given that the var name is always attached to the & symbol plus */ \
564 /* programmers can always remove const& using type traits) */ \
565 /* const bind typeof types */ \
566 BOOST_PP_LIST_FOR_EACH_I( \
567 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_TYPEDEF_,\
568 (id, typename01, 0 /* no offset */, 1 /* const-bind */ ), \
569 const_binds) \
570 /* bind typeof types */ \
571 BOOST_PP_LIST_FOR_EACH_I( \
572 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_TYPEDEF_, \
573 /* offset index with # of preceding const-binds (if any) */ \
574 ( id, typename01, BOOST_PP_LIST_SIZE(const_binds), \
575 0 /* not const-bind */ ), binds) \
576 /* const this... */ \
577 BOOST_PP_EXPR_IIF(has_const_bind_this, \
578 typedef BOOST_LOCAL_FUNCTION_AUX_TYPEOF_TYPE( \
579 BOOST_PP_EXPR_IIF(typename01, typename) \
580 ::boost::local_function::aux::add_pointed_const< \
581 BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPE(id, typename01) \
582 >::type \
583 this_ \
584 ) ; /* close typedef */ \
585 ) \
586 /* ... or, non-const this */ \
587 BOOST_PP_EXPR_IIF(has_bind_this, \
588 typedef BOOST_LOCAL_FUNCTION_AUX_TYPEOF_TYPE( \
589 BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPE(id, typename01) \
590 this_ \
591 ) ; /* close typedef */ \
592 )
593
594 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_MEMBER_DECLS_( \
595 id, typename01, const_binds, has_const_bind_this, binds, has_bind_this)\
596 /* run-time: it is faster if call `operator()` just accesses member */ \
597 /* references to the ScopeExit struct instead of accessing the bind */ \
598 /* struct at each call (these mem refs are init by the constructor) */ \
599 BOOST_PP_LIST_FOR_EACH_I( /* const bind member references */ \
600 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_DECL_,\
601 ( id, typename01, 0 /* no offset */, 1 /* const */ ), \
602 const_binds) \
603 BOOST_PP_LIST_FOR_EACH_I( /* bind member references */ \
604 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_DECL_,\
605 /* offset index of # of const-binds (could be 0) */ \
606 ( id, typename01, BOOST_PP_LIST_SIZE(const_binds), \
607 0 /* no const */ ), binds) \
608 /* bind this const or not (pointed-const is not added here because */ \
609 /* this is a reference, it is added to the this_ body param instead */ \
610 BOOST_PP_EXPR_IIF(BOOST_PP_BITOR(has_bind_this, has_const_bind_this), \
611 /* this is * so no & */ \
612 BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPE(id, typename01) \
613 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_MEMBER_THIS_ \
614 ; /* end member variable declaration */ \
615 )
616
617 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_STATIC_BINDS_( \
618 id, typename01, \
619 const_binds, has_const_bind_this, binds, has_bind_this) \
620 BOOST_PP_LIST_FOR_EACH_I( \
621 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_MAYBECONST_STATIC_BIND_MEMBER_, \
622 ( id, typename01, 0 /* no offset */, 1 /* const */ ), const_binds) \
623 BOOST_PP_LIST_FOR_EACH_I( \
624 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_MAYBECONST_STATIC_BIND_MEMBER_, \
625 /* offset of # of const-binds */ \
626 ( id, typename01, BOOST_PP_LIST_SIZE(const_binds), 0 /* const */ ), \
627 binds) \
628 BOOST_PP_IIF(BOOST_PP_BITOR(has_bind_this, \
629 has_const_bind_this), \
630 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_STATIC_BIND_MEMBER_THIS_ \
631 , \
632 BOOST_PP_TUPLE_EAT(1) \
633 )(id) \
634 /* fill with nobind_t (if no local-types as tparams) */ \
635 BOOST_PP_REPEAT(BOOST_PP_SUB(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX, \
636 BOOST_PP_IIF(BOOST_PP_BITOR(has_bind_this, has_const_bind_this), \
637 BOOST_PP_INC \
638 , \
639 BOOST_PP_TUPLE_REM(1) \
640 )(BOOST_PP_LIST_SIZE(BOOST_PP_LIST_APPEND(const_binds, binds)))), \
641 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_NOBIND_, ~)
642
643 // Functor inits.
644
645 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MEMBER_INITS_(id, typename01, \
646 const_binds, has_const_bind_this, binds, has_bind_this) \
647 BOOST_PP_EXPR_IIF(BOOST_PP_BITOR(BOOST_PP_BITOR(BOOST_PP_BITOR( \
648 BOOST_PP_LIST_IS_CONS(const_binds), BOOST_PP_LIST_IS_CONS(binds)), \
649 has_bind_this), has_const_bind_this), \
650 : \
651 ) \
652 /* init const binds */ \
653 BOOST_PP_LIST_FOR_EACH_I( \
654 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_INIT_ENUM_, \
655 ( id, 0 /* no offset */ ), const_binds) \
656 /* init plain binds */ \
657 BOOST_PP_COMMA_IF( \
658 BOOST_PP_BITAND( \
659 BOOST_PP_LIST_IS_CONS(const_binds) \
660 , BOOST_PP_LIST_IS_CONS(binds) \
661 ) \
662 ) \
663 BOOST_PP_LIST_FOR_EACH_I( \
664 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_MEMBER_INIT_ENUM_, \
665 /* offset index of # of const-binds (could be 0) */ \
666 ( id, BOOST_PP_LIST_SIZE(const_binds) ), binds) \
667 /* init `this` bind (const or not) */ \
668 BOOST_PP_COMMA_IF( \
669 BOOST_PP_BITAND( \
670 BOOST_PP_BITOR( \
671 BOOST_PP_LIST_IS_CONS(const_binds) \
672 , BOOST_PP_LIST_IS_CONS(binds) \
673 ) \
674 , BOOST_PP_BITOR(has_const_bind_this, has_bind_this) \
675 ) \
676 ) \
677 BOOST_PP_EXPR_IIF(BOOST_PP_BITOR(has_const_bind_this, has_bind_this), \
678 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_MEMBER_THIS_( \
679 static_cast< BOOST_SCOPE_EXIT_DETAIL_PARAMS_T(id)* >( \
680 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAMS_)-> \
681 BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_VAR \
682 ) \
683 )
684
685 // Functor class.
686
687 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_( \
688 id, typename01, decl_traits, params, \
689 default_count, const_binds, has_const_bind_this, binds, has_bind_this) \
690 typedef class BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CLASS_TYPE_(id) \
691 /* run-time: do not use base class to allow for compiler optimizations */ \
692 { \
693 /* function type */ \
694 private: \
695 typedef \
696 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_F_(id, typename01, \
697 decl_traits, 1 /* has type */, \
698 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_F_TYPE_) \
699 ; \
700 /* functor type -- this type cannot have ID postfix because it is */ \
701 /* used the `NAME` macro (this symbol is within functor class so */ \
702 /* it does not have to have ID postfix), must be public so it */ \
703 /* can be accessed by `NAME` macro from outside this class */ \
704 public: \
705 typedef BOOST_PP_EXPR_IIF(typename01, typename) \
706 BOOST_IDENTITY_TYPE(( /* IDENTITY for template param comma */ \
707 ::boost::local_function::aux::function< \
708 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_F_TYPE_ \
709 , default_count \
710 BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS,\
711 BOOST_PP_TUPLE_EAT(6) \
712 , \
713 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_BIND_TYPES_\
714 )(id, typename01, const_binds, has_const_bind_this, \
715 binds, has_bind_this) \
716 > \
717 )) \
718 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_TYPE \
719 ; \
720 private: \
721 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_TYPEOF_TYPEDEFS_( \
722 id, typename01, \
723 const_binds, has_const_bind_this, binds, has_bind_this) \
724 public: \
725 /* public trait interface following Boost.FunctionTraits names */ \
726 /* (traits must be defined in both this and the global functor) */ \
727 enum { arity = ::boost::function_traits< /* can't use static data */ \
728 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_F_TYPE_ >::arity }; \
729 typedef BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPE(id, typename01) \
730 result_type; \
731 BOOST_PP_LIST_FOR_EACH_I( \
732 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_ARG_TYPEDEF_, \
733 typename01, params) \
734 /* constructor */ \
735 inline explicit BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CLASS_TYPE_(id)( \
736 void* BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAMS_) \
737 /* NOTE: there is no way to wrap member initializer commas */ \
738 /* within paren so you must handle these commas manually if */ \
739 /* expanding this macro within another macro */ \
740 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MEMBER_INITS_(id, typename01,\
741 const_binds, has_const_bind_this, binds, has_bind_this) \
742 { /* do nothing */ } \
743 /* run-time: implement `operator()` (and for all default params) so */ \
744 /* this obj can be used directly as a functor for C++03 extensions */ \
745 /* and optimized macros */ \
746 BOOST_PP_REPEAT( \
747 /* PP_INC to handle no dflt (EXPAND for MVSC) */ \
748 BOOST_PP_EXPAND(BOOST_PP_INC(default_count)), \
749 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CALL_FOR_DEFAULTS_,\
750 ( BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CALL_, id, typename01 \
751 , decl_traits, params, const_binds, has_const_bind_this, binds \
752 , has_bind_this ) ) \
753 /* compliance: trick to pass this local class as a template param */ \
754 /* on pure C++03 without non C++03 extension */ \
755 /* performance: this trick introduced _one_ indirect function call */ \
756 /* via a function pointer that is usually not inlined by compliers */ \
757 /* thus increasing run-time (also another trick using a base */ \
758 /* interface class was investigated but virtual calls also cannot */ \
759 /* inlined plus they require virtual table lookups to the "virtual */ \
760 /* call trick" measured longer run-times than this "static call */ \
761 /* trick") */ \
762 BOOST_PP_REPEAT( \
763 /* PP_INC to handle no dflt (EXPAND for MVSC) */ \
764 BOOST_PP_EXPAND(BOOST_PP_INC(default_count)), \
765 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_CALL_FOR_DEFAULTS_,\
766 ( BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_, id \
767 , typename01, decl_traits, params, const_binds \
768 , has_const_bind_this, binds, has_bind_this ) ) \
769 inline static void BOOST_LOCAL_FUNCTION_AUX_FUNCTION_INIT_CALL_FUNC( \
770 void* object \
771 , BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_TYPE& functor \
772 ) { \
773 functor.BOOST_LOCAL_FUNCTION_AUX_FUNCTION_INIT_CALL_FUNC( \
774 object \
775 BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS,\
776 BOOST_PP_TUPLE_EAT(6) \
777 , \
778 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_COMMA_STATIC_BINDS_ \
779 )(id, typename01, const_binds, has_const_bind_this, \
780 binds, has_bind_this) \
781 BOOST_PP_REPEAT( /* INC to handle no dflt (EXPAND for MVSC) */ \
782 BOOST_PP_EXPAND(BOOST_PP_INC(default_count)), \
783 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_STATIC_CALL_COMMA_FUNC_ADDR_, \
784 ~) \
785 ); \
786 } \
787 private: \
788 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BIND_MEMBER_DECLS_(id, \
789 typename01, const_binds, has_const_bind_this, binds, \
790 has_bind_this) \
791 /* this decl allows for nesting (local functions, etc) as */ \
792 /* it makes the args variable visible within the body code (which */ \
793 /* cannot be static); this is for compilation only as the args */ \
794 /* variable is actually declared by the 1st enclosing local func */ \
795 boost::scope_exit::detail::undeclared \
796 BOOST_LOCAL_FUNCTION_AUX_DECL_ARGS_VAR; \
797 /* body function (unfortunately, cannot be static to allow access */ \
798 /* to member var with local function name for recursion but doing */ \
799 /* so also allows the body to misuse `this` instead of `this_`) */ \
800 inline BOOST_LOCAL_FUNCTION_AUX_CODE_RESULT_TYPE(id, typename01) \
801 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_BODY_FUNC_( \
802 /* const binds */ \
803 BOOST_PP_LIST_FOR_EACH_I( \
804 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_DECL_ENUM_, \
805 ( id, typename01, 0 /* no offset */, 1 /* const */ ), \
806 const_binds) \
807 /* plain binds */ \
808 BOOST_PP_COMMA_IF( \
809 BOOST_PP_BITAND( \
810 BOOST_PP_LIST_IS_CONS(const_binds) \
811 , BOOST_PP_LIST_IS_CONS(binds) \
812 ) \
813 ) \
814 BOOST_PP_LIST_FOR_EACH_I( \
815 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_MAYBECONST_BIND_DECL_ENUM_, \
816 /* offset index of # of const-binds (could be 0) */ \
817 ( id, typename01, BOOST_PP_LIST_SIZE(const_binds), \
818 0 /* not const-bind */ ), binds) \
819 /* `this` bind */ \
820 BOOST_PP_COMMA_IF( \
821 BOOST_PP_BITAND( \
822 BOOST_PP_BITOR( \
823 BOOST_PP_LIST_IS_CONS(const_binds) \
824 , BOOST_PP_LIST_IS_CONS(binds) \
825 ) \
826 , BOOST_PP_BITOR(has_const_bind_this, has_bind_this) \
827 ) \
828 ) \
829 /* const pointer to const object */ \
830 BOOST_PP_EXPR_IIF(has_const_bind_this, \
831 BOOST_PP_EXPR_IIF(typename01, typename) \
832 ::boost::local_function::aux::add_pointed_const< \
833 BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPE(id, \
834 typename01) \
835 >::type \
836 const this_ /* special name to access object this */ \
837 ) \
838 /* const pointer to non-const object */ \
839 BOOST_PP_EXPR_IIF(has_bind_this, \
840 BOOST_LOCAL_FUNCTION_AUX_CODE_BIND_THIS_TYPE(id, \
841 typename01) \
842 const this_ /* special name to access object this */ \
843 ) \
844 /* params (last because they can have defaults) */ \
845 BOOST_PP_COMMA_IF( \
846 BOOST_PP_BITAND( \
847 BOOST_PP_BITOR( \
848 BOOST_PP_BITOR( \
849 BOOST_PP_LIST_IS_CONS(const_binds) \
850 , BOOST_PP_LIST_IS_CONS(binds) \
851 ) \
852 , BOOST_PP_BITOR(has_const_bind_this, \
853 has_bind_this) \
854 ) \
855 , BOOST_PP_LIST_IS_CONS(params) \
856 ) \
857 ) \
858 BOOST_PP_LIST_FOR_EACH_I( \
859 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_PARAM_DECL_ENUM_, \
860 1 /* with defaults */, params) \
861 ) /* end body function params */ \
862 /* cannot be const because recursive functor is non const member */\
863 /* user local function definition `{ ... }` will follow here */ \
864 /* `END` macro will close function class decl `};` here */
865
866 // PUBLIC //
867
868 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_TYPE \
869 BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (functor_type) )
870
871 #define BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR(id, typename01, decl_traits) \
872 BOOST_LOCAL_FUNCTION_AUX_CODE_FUNCTOR_(id, typename01, decl_traits \
873 /* params (might have defaults) */ \
874 , BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_PARAMS(decl_traits) \
875 , BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_PARAMS_DEFAULT_COUNT( \
876 decl_traits) \
877 /* const bind vars (`this` excluded) */ \
878 , BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BINDS(decl_traits) \
879 /* if const bind `this` is present */ \
880 , BOOST_PP_LIST_IS_CONS( \
881 BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_CONST_BIND_THIS_TYPES( \
882 decl_traits)) \
883 /* bind (non-const) vars (`this` excluded) */ \
884 , BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BINDS(decl_traits) \
885 /* if (non-const) bind `this` is present */ \
886 , BOOST_PP_LIST_IS_CONS( \
887 BOOST_LOCAL_FUNCTION_AUX_PP_DECL_TRAITS_BIND_THIS_TYPES( \
888 decl_traits)) \
889 )
890
891 #endif // #include guard
892