_ind = RPC_HEADER_SZ;
}
- template <class OutputIterator>
- void iterate(OutputIterator i, int n) {
- while (n--) {
- typename OutputIterator::value_type t;
- *this >> t;
- *i++ = t;
- }
+ template <class A>
+ inline A grab() {
+ A a;
+ *this >> a;
+ return a;
}
};
return u >> d.first >> d.second;
}
+template <size_t...> struct tuple_indices {};
+template <size_t S, class IntTuple, size_t E> struct make_indices_imp;
+template <size_t S, size_t ...Indices, size_t E> struct make_indices_imp<S, tuple_indices<Indices...>, E> {
+ typedef typename make_indices_imp<S+1, tuple_indices<Indices..., S>, E>::type type;
+};
+template <size_t E, size_t ...Indices> struct make_indices_imp<E, tuple_indices<Indices...>, E> {
+ typedef tuple_indices<Indices...> type;
+};
+template <size_t E, size_t S = 0> struct make_tuple_indices {
+ typedef typename make_indices_imp<S, tuple_indices<>, E>::type type;
+};
+
+struct VerifyOnFailure {
+ static inline int unmarshall_args_failure() {
+ VERIFY(0);
+ return 0;
+ }
+};
+
+typedef std::function<int(unmarshall &, marshall &)> handler;
+
+using std::move;
+using std::get;
+using std::tuple;
+using std::decay;
+
+#include <iostream>
+
+template <class F, class R, class args_type, size_t ...Indices>
+typename std::enable_if<!std::is_member_function_pointer<F>::value, int>::type
+invoke(F f, void *, R & r, args_type & t, tuple_indices<Indices...>) {
+ return f(r, move(get<Indices>(t))...);
+}
+
+template <class F, class C, class R, class args_type, size_t ...Indices>
+typename std::enable_if<std::is_member_function_pointer<F>::value, int>::type
+invoke(F f, C *c, R & r, args_type & t, tuple_indices<Indices...>) {
+ return (c->*f)(r, move(get<Indices>(t))...);
+}
+
+template <class Functor,
+ class Instance,
+ class Signature,
+ class ErrorHandler=VerifyOnFailure> struct marshalled_func_imp;
+
+template <class F, class C, class ErrorHandler, class R, class... Args>
+struct marshalled_func_imp<F, C, int(R&, Args...), ErrorHandler> {
+ using result_type = R;
+ using args_type = tuple<typename decay<Args>::type...>;
+ using index_type = typename make_tuple_indices<sizeof...(Args)>::type;
+
+ static inline int call(F f, C *c, unmarshall &u, marshall &m) {
+ args_type t{std::move(std::tuple<Args...>{u.grab<Args>()...})};
+ 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<F>::type f_ = f;
+ return new handler([f_, c](unmarshall &u, marshall &m) -> int {
+ return call(f_, c, u, m);
+ });
+ }
+};
+
+template <class Functor,
+ class Signature,
+ class ErrorHandler=VerifyOnFailure> struct marshalled_func;
+
+template <class F, class ErrorHandler, class... Args>
+struct marshalled_func<F, int(*)(Args...), ErrorHandler> :
+ public marshalled_func_imp<F, void, int(Args...), ErrorHandler> {};
+
+template <class F, class ErrorHandler, class C, class... Args>
+struct marshalled_func<F, int(C::*)(Args...), ErrorHandler> :
+ public marshalled_func_imp<F, C, int(Args...), ErrorHandler> {};
+
+template <class F, class ErrorHandler, class Signature>
+struct marshalled_func<F, std::function<Signature>, ErrorHandler> :
+ public marshalled_func_imp<F, void, Signature, ErrorHandler> {};
+
#endif