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