X-Git-Url: http://xvm.mit.edu/gitweb/invirt/third/libt4.git/blobdiff_plain/4e881433f37417ccbda89c09ffdf936855d462d4..3efa02fb3a9f0a0566a7f3c99a1efb94e30ea4a6:/rpc/marshall_wrap.h?ds=sidebyside diff --git a/rpc/marshall_wrap.h b/rpc/marshall_wrap.h index 8e10a75..04f5268 100644 --- a/rpc/marshall_wrap.h +++ b/rpc/marshall_wrap.h @@ -3,7 +3,7 @@ #include "marshall.h" -typedef function handler; +typedef std::function handler; // // Automatic marshalling wrappers for RPC handlers @@ -17,14 +17,6 @@ typedef function handler; // // We implement an 'invoke' function for functions of the RPC handler // signature, i.e. int(R & r, const Args...) -// -// One thing we need in order to accomplish this is a way to cause the compiler -// to specialize 'invoke' with a parameter pack containing a list of indices -// for the elements of the tuple. This will allow us to call the underlying -// function with the exploded contents of the tuple. The empty type -// tuple_indices accomplishes this. It will be passed in to -// 'invoke' as a parameter which will be ignored, but its type will force the -// compiler to specialize 'invoke' appropriately. // This class encapsulates the default response to runtime unmarshalling // failures. The templated wrappers below may optionally use a different @@ -33,7 +25,6 @@ typedef function handler; struct VerifyOnFailure { static inline int unmarshall_args_failure() { VERIFY(0); - return 0; } }; @@ -43,17 +34,17 @@ struct VerifyOnFailure { // One for function pointers... template -typename enable_if::value, RV>::type -invoke(RV, F f, void *, R & r, args_type & t, tuple_indices) { - return f(r, move(get(t))...); +typename enable_if::value, RV>::type inline +invoke(RV, F f, void *, R & r, args_type & t, std::index_sequence) { + return f(r, std::get(t)...); } // And one for pointers to member functions... template -typename enable_if::value, RV>::type -invoke(RV, F f, C *c, R & r, args_type & t, tuple_indices) { - return (c->*f)(r, move(get(t))...); +typename enable_if::value, RV>::type inline +invoke(RV, F f, C *c, R & r, args_type & t, std::index_sequence) { + return (c->*f)(r, std::get(t)...); } // The class marshalled_func_imp uses partial template specialization to @@ -71,31 +62,26 @@ template -struct marshalled_func_imp { +struct marshalled_func_imp { static inline handler *wrap(F f, C *c=nullptr) { - // This type definition corresponds to an empty struct with - // template parameters running from 0 up to (# args) - 1. - using Indices = typename make_tuple_indices::type; // This type definition represents storage for f's unmarshalled // arguments. decay is (most notably) stripping off const // qualifiers. - using ArgsStorage = tuple::type...>; + using ArgsStorage = tuple::type...>; // Allocate a handler (i.e. function) to hold the lambda // which will unmarshall RPCs and call f. - return new handler([=](unmarshall &u, marshall &m) -> RV { + return new handler([=](unmarshall && u, marshall & m) -> RV { // Unmarshall each argument with the correct type and store the // result in a tuple. - ArgsStorage t{u._grab::type>()...}; + ArgsStorage t{u._grab::type>()...}; // Verify successful unmarshalling of the entire input stream. if (!u.okdone()) return (RV)ErrorHandler::unmarshall_args_failure(); // Allocate space for the RPC response -- will be passed into the // function as an lvalue reference. R r; - // Perform the invocation. Note that Indices() calls the default - // constructor of the empty struct with the special template - // parameters. - RV b = invoke(RV(), f, c, r, t, Indices()); + // Perform the invocation. + RV b = invoke(RV(), f, c, r, t, std::index_sequence_for{}); // Marshall the response. m << r; // Make like a tree. @@ -121,7 +107,7 @@ struct marshalled_func : public marshalled_func_imp {}; template -struct marshalled_func> : +struct marshalled_func> : public marshalled_func_imp {}; #endif