MOAR TEMPLATE MAGIC
[invirt/third/libt4.git] / rpc / marshall.h
index 20b9c07..98856e4 100644 (file)
@@ -52,6 +52,8 @@ typedef int rpc_sz_t;
 #define DEFAULT_RPC_SZ 1024
 #define RPC_HEADER_SZ (max(sizeof(request_header), sizeof(reply_header)) + sizeof(rpc_sz_t))
 
+struct pass { template <typename... Args> inline pass(Args&&...) {} };
+
 class marshall {
     private:
         char *buf_;     // Base of the raw bytes buffer (dynamically readjusted)
@@ -67,10 +69,7 @@ class marshall {
             }
         }
     public:
-        struct pass { template <typename... Args> inline pass(Args&&...) {} };
-
         template <typename... Args>
-
         marshall(const Args&... args) {
             buf_ = (char *) malloc(sizeof(char)*DEFAULT_RPC_SZ);
             VERIFY(buf_);
@@ -407,4 +406,33 @@ template <class F, class ErrorHandler, class Signature>
 struct marshalled_func<F, ErrorHandler, function<Signature>> :
     public marshalled_func_imp<F, void, Signature, ErrorHandler> {};
 
+template <class ...Args, size_t ...Indices> unmarshall &
+tuple_unmarshall_imp(unmarshall & u, tuple<Args &...> t, tuple_indices<Indices...>) {
+    (void)pass{(u >> get<Indices>(t))...};
+    return u;
+}
+
+template <class... Args> unmarshall &
+operator>>(unmarshall & u, tuple<Args &...> && t) {
+    using Indices = typename make_tuple_indices<sizeof...(Args)>::type;
+    return tuple_unmarshall_imp(u, t, Indices());
+}
+
+template <class ...Args, size_t ...Indices> marshall &
+tuple_marshall_imp(marshall & m, tuple<Args...> & t, tuple_indices<Indices...>) {
+    (void)pass{(m << get<Indices>(t))...};
+    return m;
+}
+
+template <class... Args> marshall &
+operator<<(marshall & m, tuple<Args...> && t) {
+    using Indices = typename make_tuple_indices<sizeof...(Args)>::type;
+    return tuple_marshall_imp(m, t, Indices());
+}
+
+// for structs or classes containing a MEMBERS declaration
+#define MARSHALLABLE(_c_) \
+inline unmarshall & operator>>(unmarshall &u, _c_ &a) { return u >> a._tuple_(); } \
+inline marshall & operator<<(marshall &m, _c_ a) { return m << a._tuple_(); }
+
 #endif