diff --git a/include/fc/json_rpc_client.hpp b/include/fc/json_rpc_client.hpp index ed3edb2..c97b391 100644 --- a/include/fc/json_rpc_client.hpp +++ b/include/fc/json_rpc_client.hpp @@ -4,16 +4,18 @@ #include #include #include +#include #include namespace fc { namespace json { + //static std::function( BOOST_PP_ENUM_PARAMS(n,A) ) > namespace detail { struct rpc_member { #define RPC_MEMBER_FUNCTOR(z,n,IS_CONST) \ - template \ - static fc::function BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n,A) > \ + template \ + static fc::function BOOST_PP_ENUM_TRAILING_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{ \ diff --git a/include/fc/json_rpc_connection.hpp b/include/fc/json_rpc_connection.hpp index 8cce426..8bebdfb 100644 --- a/include/fc/json_rpc_connection.hpp +++ b/include/fc/json_rpc_connection.hpp @@ -25,6 +25,7 @@ namespace fc { namespace json { template struct pending_result_impl : virtual public promise, virtual public pending_result { virtual void handle_result( const fc::value& s ) { + slog( "cast %s", typeid(T).name() ); this->set_value( value_cast(s) ); } protected: @@ -40,13 +41,16 @@ namespace fc { namespace json { }; - template + template struct rpc_server_method_impl : public rpc_server_method { - rpc_server_method_impl( const fc::function& f ):func(f){} + //static_assert( fc::is_tuple::type::value, "params should be a tuple" ); + rpc_server_method_impl( const fc::function& f ):func(f){} virtual value call( const value& v ) { - return value( func( fc::value_cast( v ) ) ); + // slog( "cast %s", typeid(Args).name() ); + return value( call_fused( func, fc::value_cast >( v ) ) ); + //return value( func( fc::value_cast( v )) ); } - fc::function func; + fc::function func; }; template @@ -54,8 +58,8 @@ namespace fc { namespace json { public: add_method_visitor( const fc::ptr& p, fc::json::rpc_connection& c ):_ptr(p),_con(c){} - template - void operator()( const char* name, fc::function& meth); + template + void operator()( const char* name, fc::function& meth); const fc::ptr& _ptr; fc::json::rpc_connection& _con; @@ -91,6 +95,7 @@ namespace fc { namespace json { template void add_method( const fc::string& name, const fc::function& a ) { + static_assert( is_tuple::type::value, "is tuple" ); this->add_method( name, rpc_server_method::ptr(new detail::rpc_server_method_impl(a) ) ); } @@ -121,9 +126,10 @@ namespace fc { namespace json { namespace detail { template - template - void add_method_visitor::operator()( const char* name, fc::function& meth) { - _con.add_method( name, rpc_server_method::ptr( new rpc_server_method_impl(meth) ) ); + template + void add_method_visitor::operator()( const char* name, fc::function& meth) { + _con.add_method( name, rpc_server_method::ptr( + new rpc_server_method_impl(meth) ) ); } } // namespace detail diff --git a/include/fc/tuple.hpp b/include/fc/tuple.hpp index 020a908..fb77a83 100644 --- a/include/fc/tuple.hpp +++ b/include/fc/tuple.hpp @@ -57,6 +57,7 @@ namespace fc { #define ILIST_PARAMS(z,n,data) BOOST_PP_CAT(a,n)( fc::forward( BOOST_PP_CAT(a,n) ) ) #define ILIST_PARAMS_COPY(z,n,data) BOOST_PP_CAT(a,n)( t.BOOST_PP_CAT(a,n) ) #define VISIT_PARAMS(z,n,data) v(BOOST_PP_CAT(a,n)); + #define LIST_MEMBERS_ON(z,n,data) data.BOOST_PP_CAT(a,n) #define FORWARD_PARAMS(z,n,data) fc::forward(BOOST_PP_CAT(a,n)) #define MEM_PARAMS(z,n,data) BOOST_PP_CAT(A,n) BOOST_PP_CAT(a,n); #define TUPLE(z,n,unused) \ @@ -77,13 +78,20 @@ namespace fc { template \ tuple make_tuple( BOOST_PP_ENUM( n, RREF_PARAMS, unused) ) { \ return tuple( BOOST_PP_ENUM( n, FORWARD_PARAMS,unused ) ); \ - } + } \ + template \ + auto call_fused( Functor f, Tuple&& t ) \ + -> decltype( f( BOOST_PP_ENUM( n, LIST_MEMBERS_ON, t) ) ) { \ + return f( BOOST_PP_ENUM( n, LIST_MEMBERS_ON, t) ); \ + } + template struct tuple{}; BOOST_PP_REPEAT_FROM_TO( 1, 8, TUPLE, unused ) #undef FORWARD_PARAMS #undef RREF_PARAMS + #undef LIST_MEMBERS_ON #undef ILIST_PARAMS #undef ILIST_PARAMS_COPY #undef VISIT_PARAMS @@ -99,6 +107,18 @@ namespace fc { inline tuple<> make_tuple(){ return tuple<>(); } + template + struct is_tuple { + typedef fc::false_type type; + }; + + template + struct is_tuple > { + typedef fc::true_type type; + }; + + + /* template struct tuple { diff --git a/include/fc/value_cast.hpp b/include/fc/value_cast.hpp index 7998c23..60e0ce5 100644 --- a/include/fc/value_cast.hpp +++ b/include/fc/value_cast.hpp @@ -5,6 +5,9 @@ #include #include #include +#include + +#include namespace fc { @@ -26,9 +29,9 @@ namespace fc { virtual void operator()( const double& v ){ m_out = fc::numeric_cast(v); } virtual void operator()( const bool& v ){ m_out = fc::numeric_cast(v); } virtual void operator()( const fc::string& v ) { m_out = fc::lexical_cast(v); } - virtual void operator()( const value::object& ) { FC_THROW_MSG("bad cast"); } - virtual void operator()( const value::array& ) { FC_THROW_MSG("bad cast"); } - virtual void operator()( ) { FC_THROW_MSG("bad cast"); } + virtual void operator()( const value::object& ) { FC_THROW_MSG("bad cast"); } + virtual void operator()( const value::array& ) { FC_THROW_MSG("bad cast"); } + virtual void operator()( ) { FC_THROW_MSG("bad cast"); } private: T& m_out; }; @@ -48,10 +51,10 @@ namespace fc { virtual void operator()( const float& v ){ m_out = fc::lexical_cast(v); } virtual void operator()( const double& v ){ m_out = fc::lexical_cast(v); } virtual void operator()( const bool& v ){ m_out = fc::lexical_cast(v); } - virtual void operator()( const fc::string& v ){ m_out = v; } - virtual void operator()( const value::object& ) { FC_THROW_MSG("bad cast"); } - virtual void operator()( const value::array& ) { FC_THROW_MSG("bad cast"); } - virtual void operator()( ) { FC_THROW_MSG("bad cast"); } + virtual void operator()( const fc::string& v ){ m_out = v; } + virtual void operator()( const value::object& ) { FC_THROW_MSG("bad cast"); } + virtual void operator()( const value::array& ) { FC_THROW_MSG("bad cast"); } + virtual void operator()( ) { FC_THROW_MSG("bad cast"); } private: fc::string& m_out; @@ -122,14 +125,45 @@ namespace fc { virtual void operator()( const value::array& ) { FC_THROW_MSG("bad cast");} virtual void operator()( ) { } }; + template + struct cast_if_tuple { + template + static T cast( const value& v ) { + slog( "cast non tuple %s", typeid(T).name() ); + T out; + v.visit(cast_visitor(out)); + return out; + } + }; + template<> + struct cast_if_tuple { + struct member_visitor { + member_visitor( const value& v ) + :_val(v),idx(0){} + template + void operator()( Member& m ) { + m = value_cast(_val[idx]); + ++idx; + } + const value& _val; + int idx; + }; + + template + static T cast( const value& v ) { + T out; + out.visit( member_visitor(v) ); + slog( "cast tuple" ); + // v.visit(cast_visitor(out)); + return out; + } + }; template struct cast_if_reflected { template static T cast( const value& v ) { - T out; - v.visit(cast_visitor(out)); - return out; + return cast_if_tuple::type>::template cast(v); } }; diff --git a/include/fc/value_io.hpp b/include/fc/value_io.hpp index 8aef083..de9c678 100644 --- a/include/fc/value_io.hpp +++ b/include/fc/value_io.hpp @@ -132,7 +132,7 @@ namespace fc { } else { if( !is_optional< typename fc::remove_reference::type >::type::value ) { - wlog( "unable to find name: '%1%'",name); + wlog( "unable to find name: '%s'",name); } } } diff --git a/src/json.cpp b/src/json.cpp index f6b9ac6..8097b03 100644 --- a/src/json.cpp +++ b/src/json.cpp @@ -587,7 +587,7 @@ char* read_key_val( value::object& obj, bool sc, char* in, char* end, fc::json:: if( sc ) { // if we expect a , if( *name != ',' ) { // but didn't get one if( *name != '}' ) - wlog( "expected ',' or '}' but got %1%", name ); // warn and accept name + wlog( "expected ',' or '}' but got '%s'", name ); // warn and accept name } else { // we got the exepcted , read the expected name name = fc::json::read_value( name_end, end, name_end ); } @@ -757,15 +757,15 @@ fc::value to_value( char* start, char* end, error_collector& ec ) { } case 'n': { temp_set move_end(ve,'\0'); - if( strcmp(s,"null" ) ) return value(); + if( strcmp(s,"null" ) == 0) return value(); } case 't': { temp_set move_end(ve,'\0'); - if( strcmp(s,"true" ) ) return true; + if( strcmp(s,"true" ) == 0) return true; } case 'f': { temp_set move_end(ve,'\0'); - if( strcmp(s,"false" ) ) return false; + if( strcmp(s,"false" ) == 0) return false; } default: diff --git a/src/json_rpc_connection.cpp b/src/json_rpc_connection.cpp index cf9ad7b..2854473 100644 --- a/src/json_rpc_connection.cpp +++ b/src/json_rpc_connection.cpp @@ -64,6 +64,7 @@ namespace fc { namespace json { value nul; const value& params = (p_itr != end) ? p_itr->val : nul; + slog( "params '%s'", to_string( params ).c_str() ); if( id_itr != end ) { // capture reply try { diff --git a/src/sstream.cpp b/src/sstream.cpp index ad2cc17..bb05b13 100644 --- a/src/sstream.cpp +++ b/src/sstream.cpp @@ -33,11 +33,9 @@ namespace fc { return *this; } size_t stringstream::readsome( char* buf, size_t len ) { - slog(""); return my->ss.readsome(buf,len); } istream& stringstream::read( char* buf, size_t len ) { - slog(""); my->ss.read(buf,len); return *this; } diff --git a/src/tcp_socket.cpp b/src/tcp_socket.cpp index a9fcdd8..a4e089e 100644 --- a/src/tcp_socket.cpp +++ b/src/tcp_socket.cpp @@ -9,9 +9,8 @@ namespace fc { class tcp_socket::impl { public: - impl():_sock( fc::asio::default_io_service() ){ slog( "sock %p", this); } + impl():_sock( fc::asio::default_io_service() ){ } ~impl(){ - slog( "~sock %p", this ); if( _sock.is_open() ) _sock.close(); }