#if !BOOST_PP_IS_ITERATING #ifndef CLOSURE_HPP #define CLOSURE_HPP "closure.hpp" #include #include #include #include #include #include #include // identity template struct identity { typedef T type; }; // enable_if template struct enable_if { }; template struct enable_if : identity { }; // map_integral template struct map_integral { static const T value = X; }; template const T map_integral::value; // is_function template class is_function { private: template static char check(U (*)[1]); template static char (& check(...))[2]; public: static const bool value = sizeof(check(0)) != 1; }; template const bool is_function::value; template<> class is_function : public map_integral { }; template struct is_function : public map_integral { }; // closure namespace detail { template class closure; } template class closure : public detail::closure { }; #define cv(n) \ BOOST_PP_APPLY(BOOST_PP_SEQ_ELEM( \ n, (BOOST_PP_NIL)((const))((volatile))((const volatile)) \ )) \ /**/ #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 3, CLOSURE_HPP)) #include BOOST_PP_ITERATE() #undef cv template inline typename enable_if< !is_function::value, typename closure::type >::type make_closure(T* obj, D C::* data) { assert(obj && data); return obj->*data; } template inline typename enable_if< is_function::value, typename closure::type >::type make_closure(T* obj, D C::* func) { assert(obj && func); return typename closure::type(obj, func); } #endif #elif BOOST_PP_ITERATION_DEPTH() == 1 #define i BOOST_PP_FRAME_ITERATION(1) namespace detail { template class closure::value>::type> : public identity { }; } #define BOOST_PP_ITERATION_PARAMS_2 \ (3, (0, CLOSURE_MAX_ARITY ? CLOSURE_MAX_ARITY : 15, CLOSURE_HPP)) \ /**/ #include BOOST_PP_ITERATE() #undef i #else #define j BOOST_PP_ITERATION() #define member(id) \ R (C::* BOOST_PP_APPLY(id))(BOOST_PP_ENUM_PARAMS(j, P)) cv(i) \ /**/ template class closure { public: typedef closure type; inline closure(cv(i) C* obj, member((func))) : obj_((assert(obj), obj)), func_((assert(func), func)) { return; } inline R operator()(BOOST_PP_ENUM_BINARY_PARAMS(j, P, p)) const { return (obj_->*func_)(BOOST_PP_ENUM_PARAMS(j, p)); } private: cv(i) C* obj_; member((func_)); }; #undef member #undef j #endif