X-Git-Url: http://xvm.mit.edu/gitweb/invirt/third/libt4.git/blobdiff_plain/130f2d53438eb6193accb445aca52fa8e2fe4158..4b9798f44ae94deabf87dd534337b55259272950:/rpc/marshall.h diff --git a/rpc/marshall.h b/rpc/marshall.h index 27cebbb..448240b 100644 --- a/rpc/marshall.h +++ b/rpc/marshall.h @@ -219,13 +219,11 @@ class unmarshall { _ind = RPC_HEADER_SZ; } - template - void iterate(OutputIterator i, int n) { - while (n--) { - typename OutputIterator::value_type t; - *this >> t; - *i++ = t; - } + template + inline A grab() { + A a; + *this >> a; + return a; } }; @@ -285,4 +283,89 @@ operator>>(unmarshall &u, std::pair &d) { return u >> d.first >> d.second; } +template struct tuple_indices {}; +template struct make_indices_imp; +template struct make_indices_imp, E> { + typedef typename make_indices_imp, E>::type type; +}; +template struct make_indices_imp, E> { + typedef tuple_indices type; +}; +template struct make_tuple_indices { + typedef typename make_indices_imp, E>::type type; +}; + +struct VerifyOnFailure { + static inline int unmarshall_args_failure() { + VERIFY(0); + return 0; + } +}; + +typedef std::function handler; + +using std::move; +using std::get; +using std::tuple; +using std::decay; + +#include + +template +typename std::enable_if::value, int>::type +invoke(F f, void *, R & r, args_type & t, tuple_indices) { + return f(r, move(get(t))...); +} + +template +typename std::enable_if::value, int>::type +invoke(F f, C *c, R & r, args_type & t, tuple_indices) { + return (c->*f)(r, move(get(t))...); +} + +template struct marshalled_func_imp; + +template +struct marshalled_func_imp { + using result_type = R; + using args_type = tuple::type...>; + using index_type = typename make_tuple_indices::type; + + static inline int call(F f, C *c, unmarshall &u, marshall &m) { + args_type t{std::move(std::tuple{u.grab()...})}; + if (!u.okdone()) + return ErrorHandler::unmarshall_args_failure(); + R r; + int b = invoke(f, c, r, t, index_type()); + m << r; + return b; + } + + static inline handler *wrap(F f, C *c=nullptr) { + typename decay::type f_ = f; + return new handler([f_, c](unmarshall &u, marshall &m) -> int { + return call(f_, c, u, m); + }); + } +}; + +template struct marshalled_func; + +template +struct marshalled_func : + public marshalled_func_imp {}; + +template +struct marshalled_func : + public marshalled_func_imp {}; + +template +struct marshalled_func, ErrorHandler> : + public marshalled_func_imp {}; + #endif