// Copyright 2020 Peter Dimov // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt #include #include #include #include #include #include #include template boost::json::value call_impl_( C1 & c1, R (C2::*pmf)(A...), boost::json::array const & args, std::index_sequence ) { return boost::json::value_from( (c1.*pmf)( boost::json::value_to< boost::remove_cv_ref_t >( args[ I ] )... ) ); } template boost::json::value call_impl( C1 & c1, R (C2::*pmf)(A...), boost::json::array const & args ) { if( args.size() != sizeof...(A) ) { throw std::invalid_argument( "Invalid number of arguments" ); } return call_impl_( c1, pmf, args, std::index_sequence_for() ); } template boost::json::value call( C & c, boost::string_view method, boost::json::value const & args ) { using Fd = boost::describe::describe_members; bool found = false; boost::json::value result; boost::mp11::mp_for_each([&](auto D){ if( !found && method == D.name) { result = call_impl( c, D.pointer, args.as_array() ); found = true; } }); if( !found ) { throw std::invalid_argument( "Invalid method name" ); } return result; } struct Object { std::string greet( std::string const & who ) { return "Hello, " + who + "!"; } int add( int x, int y ) { return x + y; } }; BOOST_DESCRIBE_STRUCT(Object, (), (greet, add)) #include int main() { Object obj; std::cout << call( obj, "greet", { "world" } ) << std::endl; std::cout << call( obj, "add", { 1, 2 } ) << std::endl; }