#pragma once #include #include #include #include #include #include #include namespace fc { namespace json { namespace detail { struct rpc_member { #if BOOST_NO_VARIADIC_TEMPLATES #define RPC_MEMBER_FUNCTOR(z,n,IS_CONST) \ template \ static std::function( BOOST_PP_ENUM_PARAMS(n,A) ) > \ functor( P, R (C::*mem_func)(BOOST_PP_ENUM_PARAMS(n,A)) IS_CONST, \ const rpc_connection::ptr& c = rpc_connection::ptr(), const char* name = nullptr ) { \ return [=](BOOST_PP_ENUM_BINARY_PARAMS(n,A,a))->fc::future{ \ return c->invoke( name, make_tuple(BOOST_PP_ENUM_PARAMS(n,a)) ); }; \ } BOOST_PP_REPEAT( 8, RPC_MEMBER_FUNCTOR, const ) BOOST_PP_REPEAT( 8, RPC_MEMBER_FUNCTOR, BOOST_PP_EMPTY() ) #undef RPC_MEMBER_FUNCTOR #else template static std::function(Args...)> functor( P&& p, R (C::*mem_func)(Args...), const rpc_connection::ptr& c = rpc_connection::ptr(), const char* name = nullptr ) { return [=](Args... args)->fc::future{ return c->invoke( name, make_tuple(args...) ); }; } template static std::function(Args...)> functor( P&& p, R (C::*mem_func)(Args...)const, const rpc_connection::ptr& c = rpc_connection::ptr(), const char* name = nullptr ) { return [=](Args... args)->fc::future{ return c->invoke( name, make_tuple(args...) ); }; } #endif }; struct vtable_visitor { vtable_visitor( rpc_connection::ptr& c ):_con(c){} template void operator()( const char* name, Function& memb, MemberPtr m )const { memb = rpc_member::functor( nullptr, m, _con, name ); } rpc_connection::ptr& _con; }; }; template class rpc_client : public ptr { public: rpc_client(){} rpc_client( const rpc_connection::ptr& c ):_con(c){ init(); } rpc_client( const rpc_client& c ):_con(c._con){} void set_connection( const rpc_connection::ptr& c ) { _con = c; init(); } const rpc_connection& connection()const { return _con; } private: void init() { this->_vtable.reset(new fc::detail::vtable() ); this->_vtable->template visit_other( fc::json::detail::vtable_visitor(_con) ); } rpc_connection::ptr _con; }; } } // fc::json