C++11y allows us to eliminate some boilerplate!
[invirt/third/libt4.git] / rpc / marshall_wrap.h
index b895696..04f5268 100644 (file)
@@ -17,14 +17,6 @@ typedef std::function<rpc_protocol::status(unmarshall &&, marshall &)> handler;
 //
 // We implement an 'invoke' function for functions of the RPC handler
 // signature, i.e. int(R & r, const Args...)
 //
 // 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<size_t...> 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
 
 // This class encapsulates the default response to runtime unmarshalling
 // failures.  The templated wrappers below may optionally use a different
@@ -33,7 +25,6 @@ typedef std::function<rpc_protocol::status(unmarshall &&, marshall &)> handler;
 struct VerifyOnFailure {
     static inline int unmarshall_args_failure() {
         VERIFY(0);
 struct VerifyOnFailure {
     static inline int unmarshall_args_failure() {
         VERIFY(0);
-        return 0;
     }
 };
 
     }
 };
 
@@ -43,17 +34,17 @@ struct VerifyOnFailure {
 // One for function pointers...
 
 template <class F, class R, class RV, class args_type, size_t... Indices>
 // One for function pointers...
 
 template <class F, class R, class RV, class args_type, size_t... Indices>
-typename enable_if<!is_member_function_pointer<F>::value, RV>::type inline 
-invoke(RV, F f, void *, R & r, args_type & t, tuple_indices<Indices...>) {
-    return f(r, get<Indices>(t)...);
+typename enable_if<!std::is_member_function_pointer<F>::value, RV>::type inline 
+invoke(RV, F f, void *, R & r, args_type & t, std::index_sequence<Indices...>) {
+    return f(r, std::get<Indices>(t)...);
 }
 
 // And one for pointers to member functions...
 
 template <class F, class C, class RV, class R, class args_type, size_t... Indices>
 }
 
 // And one for pointers to member functions...
 
 template <class F, class C, class RV, class R, class args_type, size_t... Indices>
-typename enable_if<is_member_function_pointer<F>::value, RV>::type inline 
-invoke(RV, F f, C *c, R & r, args_type & t, tuple_indices<Indices...>) {
-    return (c->*f)(r, get<Indices>(t)...);
+typename enable_if<std::is_member_function_pointer<F>::value, RV>::type inline 
+invoke(RV, F f, C *c, R & r, args_type & t, std::index_sequence<Indices...>) {
+    return (c->*f)(r, std::get<Indices>(t)...);
 }
 
 // The class marshalled_func_imp uses partial template specialization to
 }
 
 // The class marshalled_func_imp uses partial template specialization to
@@ -76,23 +67,21 @@ struct marshalled_func_imp<F, C, RV(R &, Args...), ErrorHandler> {
         // This type definition represents storage for f's unmarshalled
         // arguments.  decay is (most notably) stripping off const
         // qualifiers.
         // This type definition represents storage for f's unmarshalled
         // arguments.  decay is (most notably) stripping off const
         // qualifiers.
-        using ArgsStorage = tuple<typename decay<Args>::type...>;
+        using ArgsStorage = tuple<typename std::decay<Args>::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 {
             // Unmarshall each argument with the correct type and store the
             // result in a tuple.
         // 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 {
             // Unmarshall each argument with the correct type and store the
             // result in a tuple.
-            ArgsStorage t{u._grab<typename decay<Args>::type>()...};
+            ArgsStorage t{u._grab<typename std::decay<Args>::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;
             // 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 TUPLE_INDICES calls the
-            // default constructor of an empty struct with template parameters
-            // running from 0 up to (# args) - 1.
-            RV b = invoke(RV(), f, c, r, t, TUPLE_INDICES(Args));
+            // Perform the invocation.
+            RV b = invoke(RV(), f, c, r, t, std::index_sequence_for<Args...>{});
             // Marshall the response.
             m << r;
             // Make like a tree.
             // Marshall the response.
             m << r;
             // Make like a tree.