#include #include #include #include #include #include #include #include #include #include #define NAME(seq) BOOST_PP_SEQ_ELEM(1, seq) #define RESULT(seq) BOOST_PP_SEQ_ELEM(0, seq) #define PARM_LIST(seq) BOOST_PP_SEQ_ELEM(2, seq) #define BODY(seq) BOOST_PP_SEQ_ELEM(3, seq) #define CLOSED(seq) BOOST_PP_SEQ_REST_N(4, seq) #define MAKE_TYPE(unused, name, x) \ typedef typeof(x)& \ BOOST_PP_CAT \ (x, BOOST_PP_CAT \ (_, BOOST_PP_CAT \ (name, _type))); \ /**/ #define MAKE_NAME(unused, name, x) \ BOOST_PP_CAT(x, BOOST_PP_CAT(_, BOOST_PP_CAT( name, _type))) x; \ /**/ #define ENUM_CLOSURE_TYPES(name, seq) \ BOOST_PP_SEQ_FOR_EACH \ (MAKE_TYPE, name, seq) \ /**/ #define ENUM_CLOSURE_ELEMENTS(name, seq) \ BOOST_PP_SEQ_FOR_EACH \ (MAKE_NAME, name, seq) \ /**/ #define MAKE_BLOCK_NAME(name) \ BOOST_PP_CAT( name, _block) \ /**/ #define MAKE_BLOCK_TYPE(name) \ BOOST_PP_CAT( name, _block_type)\ /**/ #define ENUM_CLOSURE_LIST(parm) \ BOOST_PP_SEQ_ENUM(CLOSED(parm)) \ /**/ #define MAKE_CLOSURE_BLOCK(parm) \ struct MAKE_BLOCK_TYPE(NAME(parm)) { \ ENUM_CLOSURE_ELEMENTS(NAME(parm), CLOSED(parm)) \ } MAKE_BLOCK_NAME(NAME(parm)) = { ENUM_CLOSURE_LIST(parm) }; \ /**/ template struct closure_base; template struct closure_base { typedef R result_type; virtual result_type operator()() const = 0; }; template struct closure_base { typedef R result_type; virtual result_type operator()(T1 a) const = 0; }; template struct closure_base { typedef R result_type; virtual result_type operator()(T1 a, T2 b) const = 0 ; }; template struct closure_base { typedef R result_type; virtual result_type operator()(T1 a, T2 b, T3 c) const = 0; }; template struct closure_ptr; template struct closure_ptr { typedef R result_type; closure_base & p; result_type operator()() const { return p(); } }; template struct closure_ptr { typedef R result_type; closure_base & p; result_type operator()(T1 a) const { return p(a); } }; template struct closure_ptr { typedef R result_type; closure_base & p; result_type operator()(T1 a, T2 b) const { return p(a, b); } ; }; template struct closure_ptr { typedef R result_type; closure_base & p; result_type operator()(T1 a, T2 b, T3 c) const { return p(a, b, c); }; }; #define CLOSURE(parm) \ ENUM_CLOSURE_TYPES(NAME(parm), CLOSED(parm)) \ MAKE_CLOSURE_BLOCK(parm) \ struct BOOST_PP_CAT(lambda_, NAME(parm)) : \ closure_base \ , MAKE_BLOCK_TYPE(NAME(parm)) { \ BOOST_PP_CAT(lambda_, NAME(parm)) \ (MAKE_BLOCK_TYPE(NAME(parm)) super) : MAKE_BLOCK_TYPE(NAME(parm))(super){}\ RESULT(parm) operator() PARM_LIST(parm) const \ BODY(parm) \ } BOOST_PP_CAT \ (lambda_, BOOST_PP_CAT (NAME(parm), _instance)) \ (MAKE_BLOCK_NAME(NAME(parm))); \ const closure_ptr NAME(parm) = \ { BOOST_PP_CAT \ (lambda_, BOOST_PP_CAT(NAME(parm), _instance)) }; \ /**/ struct dummy { const int & a; const int & b; } v = { 1, 1}; int main() { int a = 1; std::string x = "hello"; CLOSURE((void)(foo)((int b, std::string const& y)) ({ a = b; x = y; }) (a)(x)); foo(10, "bye"); std::vector v(100); a = 0; CLOSURE((int)(gen_body)(()) ({ return a++; })(a)); std::generate(v.begin(), v.end(), gen_body); CLOSURE((void)(for_each_body)((int x)) ({ std::cout << x + a << "\n"; })(a)) std::for_each(v.begin(), v.end(), for_each_body); }