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 
893