]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 |