functor.hpp 42 KB

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