You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by be...@apache.org on 2012/01/27 02:25:15 UTC

svn commit: r1236485 [4/7] - in /incubator/mesos/trunk: ./ include/mesos/ src/common/ src/exec/ src/local/ src/log/ src/master/ src/python/native/ src/sched/ src/slave/ src/tests/ src/zookeeper/ third_party/libprocess/ third_party/libprocess/include/pr...

Modified: incubator/mesos/trunk/third_party/libprocess/include/process/dispatch.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/libprocess/include/process/dispatch.hpp?rev=1236485&r1=1236484&r2=1236485&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/libprocess/include/process/dispatch.hpp (original)
+++ incubator/mesos/trunk/third_party/libprocess/include/process/dispatch.hpp Fri Jan 27 01:25:13 2012
@@ -1,2093 +1,496 @@
 #ifndef __PROCESS_DISPATCH_HPP__
 #define __PROCESS_DISPATCH_HPP__
 
-#include <process/process.hpp>
+#include <tr1/functional>
+#include <tr1/memory> // TODO(benh): Replace all shared_ptr with unique_ptr.
 
-// Provides "dispatch" abilities for a process. That is, given a local
-// (i.e., typed) pid, one can dispatch a method to it more naturally
-// then sending a string and some bytes of data. This provides better
-// type safety.
+#include <process/process.hpp>
+#include <process/preprocessor.hpp>
 
 namespace process {
 
-/**
- * Dispatches a void method on a process.
- *
- * @param pid receiver of message
- * @param method method to invoke on receiver
- */
-template <typename T>
-void dispatch(const PID<T>& pid,
-              void (T::*method)());
-
-template <typename T>
-void dispatch(const Process<T>& process,
-              void (T::*method)());
-
-template <typename T>
-void dispatch(const Process<T>* process,
-              void (T::*method)());
-
-
-/**
- * Dispatches a void method on a process.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 argument to pass to method
- */
-template <typename T, typename P1, typename A1>
-void dispatch(const PID<T>& pid,
-              void (T::*method)(P1),
-              A1 a1);
-
-template <typename T, typename P1, typename A1>
-void dispatch(const Process<T>& process,
-              void (T::*method)(P1),
-              A1 a1);
-
-template <typename T, typename P1, typename A1>
-void dispatch(const Process<T>* process,
-              void (T::*method)(P1),
-              A1 a1);
-
-
-/**
- * Dispatches a void method on a process.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 first argument to pass to method
- * @param a2 second argument to pass to method
- */
-template <typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-void dispatch(const PID<T>& pid,
-              void (T::*method)(P1, P2),
-              A1 a1, A2 a2);
-
-template <typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-void dispatch(const Process<T>& process,
-              void (T::*method)(P1, P2),
-              A1 a1, A2 a2);
-
-template <typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-void dispatch(const Process<T>* process,
-              void (T::*method)(P1, P2),
-              A1 a1, A2 a2);
-
-
-/**
- * Dispatches a void method on a process.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 first argument to pass to method
- * @param a2 second argument to pass to method
- * @param a3 second argument to pass to method
- */
-template <typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-void dispatch(const PID<T>& pid,
-              void (T::*method)(P1, P2, P3),
-              A1 a1, A2 a2, A3 a3);
-
-template <typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-void dispatch(const Process<T>& process,
-              void (T::*method)(P1, P2, P3),
-              A1 a1, A2 a2, A3 a3);
-
-template <typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-void dispatch(const Process<T>* process,
-              void (T::*method)(P1, P2, P3),
-              A1 a1, A2 a2, A3 a3);
-
-
-/**
- * Dispatches a void method on a process.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 first argument to pass to method
- * @param a2 second argument to pass to method
- * @param a3 third argument to pass to method
- * @param a4 fourth argument to pass to method
- */
-template <typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-void dispatch(const PID<T>& pid,
-              void (T::*method)(P1, P2, P3, P4),
-              A1 a1, A2 a2, A3 a3, A4 a4);
-
-template <typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-void dispatch(const Process<T>& process,
-              void (T::*method)(P1, P2, P3, P4),
-              A1 a1, A2 a2, A3 a3, A4 a4);
-
-template <typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-void dispatch(const Process<T>* process,
-              void (T::*method)(P1, P2, P3, P4),
-              A1 a1, A2 a2, A3 a3, A4 a4);
-
-
-/**
- * Dispatches a void method on a process.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 first argument to pass to method
- * @param a2 second argument to pass to method
- * @param a3 third argument to pass to method
- * @param a4 fourth argument to pass to method
- * @param a5 fifth argument to pass to method
- */
-template <typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-void dispatch(const PID<T>& pid,
-              void (T::*method)(P1, P2, P3, P4, P5),
-              A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
-
-template <typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-void dispatch(const Process<T>& process,
-              void (T::*method)(P1, P2, P3, P4, P5),
-              A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
-
-template <typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-void dispatch(const Process<T>* process,
-              void (T::*method)(P1, P2, P3, P4, P5),
-              A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
-
-
-/**
- * Dispatches a method on a process and returns the future that
- * corresponds to the result of executing the method.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @return future corresponding to the result of executing the method
- */
-template <typename R, typename T>
-Future<R> dispatch(const PID<T>& pid,
-                   Promise<R> (T::*method)());
-
-template <typename R, typename T>
-Future<R> dispatch(const Process<T>& process,
-                   Promise<R> (T::*method)());
-
-template <typename R, typename T>
-Future<R> dispatch(const Process<T>* process,
-                   Promise<R> (T::*method)());
-
-
-/**
- * Dispatches a method on a process and returns the future that
- * corresponds to the result of executing the method.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 argument to pass to method
- * @return future corresponding to the result of executing the method
- */
-template <typename R, typename T,
-          typename P1, typename A1>
-Future<R> dispatch(const PID<T>& pid,
-                   Promise<R> (T::*method)(P1),
-                   A1 a1);
-
-template <typename R, typename T,
-          typename P1, typename A1>
-Future<R> dispatch(const Process<T>& process,
-                   Promise<R> (T::*method)(P1),
-                   A1 a1);
-
-template <typename R, typename T,
-          typename P1, typename A1>
-Future<R> dispatch(const Process<T>* process,
-                   Promise<R> (T::*method)(P1),
-                   A1 a1);
-
-
-/**
- * Dispatches a method on a process and returns the future that
- * corresponds to the result of executing the method.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 first argument to pass to method
- * @param a2 second argument to pass to method
- * @return future corresponding to the result of executing the method
- */
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-Future<R> dispatch(const PID<T>& pid,
-                   Promise<R> (T::*method)(P1, P2),
-                   A1 a1, A2 a2);
-
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-Future<R> dispatch(const Process<T>& process,
-                   Promise<R> (T::*method)(P1, P2),
-                   A1 a1, A2 a2);
-
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-Future<R> dispatch(const Process<T>* process,
-                   Promise<R> (T::*method)(P1, P2),
-                   A1 a1, A2 a2);
-
-
-/**
- * Dispatches a method on a process and returns the future that
- * corresponds to the result of executing the method.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 first argument to pass to method
- * @param a2 second argument to pass to method
- * @param a3 second argument to pass to method
- * @return future corresponding to the result of executing the method
- */
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-Future<R> dispatch(const PID<T>& pid,
-                   Promise<R> (T::*method)(P1, P2, P3),
-                   A1 a1, A2 a2, A3 a3);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-Future<R> dispatch(const Process<T>& process,
-                   Promise<R> (T::*method)(P1, P2, P3),
-                   A1 a1, A2 a2, A3 a3);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-Future<R> dispatch(const Process<T>* process,
-                   Promise<R> (T::*method)(P1, P2, P3),
-                   A1 a1, A2 a2, A3 a3);
-
-
-/**
- * Dispatches a method on a process and returns the future that
- * corresponds to the result of executing the method.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 first argument to pass to method
- * @param a2 second argument to pass to method
- * @param a3 third argument to pass to method
- * @param a4 fourth argument to pass to method
- * @return future corresponding to the result of executing the method
- */
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-Future<R> dispatch(const PID<T>& pid,
-                   Promise<R> (T::*method)(P1, P2, P3, P4),
-                   A1 a1, A2 a2, A3 a3, A4 a4);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-Future<R> dispatch(const Process<T>& process,
-                   Promise<R> (T::*method)(P1, P2, P3, P4),
-                   A1 a1, A2 a2, A3 a3, A4 a4);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-Future<R> dispatch(const Process<T>* process,
-                   Promise<R> (T::*method)(P1, P2, P3, P4),
-                   A1 a1, A2 a2, A3 a3, A4 a4);
-
-
-/**
- * Dispatches a method on a process and returns the future that
- * corresponds to the result of executing the method.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 first argument to pass to method
- * @param a2 second argument to pass to method
- * @param a3 third argument to pass to method
- * @param a4 fourth argument to pass to method
- * @param a5 fifth argument to pass to method
- * @return future corresponding to the result of executing the method
- */
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-Future<R> dispatch(const PID<T>& pid,
-                   Promise<R> (T::*method)(P1, P2, P3, P4, P5),
-                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-Future<R> dispatch(const Process<T>& process,
-                   Promise<R> (T::*method)(P1, P2, P3, P4, P5),
-                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-Future<R> dispatch(const Process<T>* process,
-                   Promise<R> (T::*method)(P1, P2, P3, P4, P5),
-                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
-
-
-/**
- * Dispatches a method on a process and returns the future that
- * corresponds to the result of executing the method.
- *
- * @param pid receiver of message
- * @param method method to invoke on receiver
- */
-template <typename R, typename T>
-Future<R> dispatch(const PID<T>& pid,
-                   R (T::*method)());
-
-template <typename R, typename T>
-Future<R> dispatch(const Process<T>& process,
-                   R (T::*method)());
-
-template <typename R, typename T>
-Future<R> dispatch(const Process<T>* process,
-                   R (T::*method)());
-
-
-/**
- * Dispatches a method on a process and returns the future that
- * corresponds to the result of executing the method.
- *
- * @param pid receiver of message
- * @param method method to invoke on receiver
- * @param a1 first argument to pass to method
- */
-template <typename R, typename T,
-          typename P1, typename A1>
-Future<R> dispatch(const PID<T>& pid,
-                   R (T::*method)(P1),
-                   A1 a1);
-
-template <typename R, typename T,
-          typename P1, typename A1>
-Future<R> dispatch(const Process<T>& process,
-                   R (T::*method)(P1),
-                   A1 a1);
-
-template <typename R, typename T, typename P1, typename A1>
-Future<R> dispatch(const Process<T>* process,
-                   R (T::*method)(P1),
-                   A1 a1);
-
-
-/**
- * Dispatches a method on a process and returns the future that
- * corresponds to the result of executing the method.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 first argument to pass to method
- * @param a2 second argument to pass to method
- * @return future corresponding to the result of executing the method
- */
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-Future<R> dispatch(const PID<T>& pid,
-                   R (T::*method)(P1, P2),
-                   A1 a1, A2 a2);
-
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-Future<R> dispatch(const Process<T>& process,
-                   R (T::*method)(P1, P2),
-                   A1 a1, A2 a2);
-
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-Future<R> dispatch(const Process<T>* process,
-                   R (T::*method)(P1, P2),
-                   A1 a1, A2 a2);
-
-
-/**
- * Dispatches a method on a process and returns the future that
- * corresponds to the result of executing the method.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 first argument to pass to method
- * @param a2 second argument to pass to method
- * @param a3 second argument to pass to method
- * @return future corresponding to the result of executing the method
- */
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-Future<R> dispatch(const PID<T>& pid,
-                   R (T::*method)(P1, P2, P3),
-                   A1 a1, A2 a2, A3 a3);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-Future<R> dispatch(const Process<T>& process,
-                   R (T::*method)(P1, P2, P3),
-                   A1 a1, A2 a2, A3 a3);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-Future<R> dispatch(const Process<T>* process,
-                   R (T::*method)(P1, P2, P3),
-                   A1 a1, A2 a2, A3 a3);
-
-
-/**
- * Dispatches a method on a process and returns the future that
- * corresponds to the result of executing the method.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 first argument to pass to method
- * @param a2 second argument to pass to method
- * @param a3 third argument to pass to method
- * @param a4 fourth argument to pass to method
- * @return future corresponding to the result of executing the method
- */
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-Future<R> dispatch(const PID<T>& pid,
-                   R (T::*method)(P1, P2, P3, P4),
-                   A1 a1, A2 a2, A3 a3, A4 a4);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-Future<R> dispatch(const Process<T>& process,
-                   R (T::*method)(P1, P2, P3, P4),
-                   A1 a1, A2 a2, A3 a3, A4 a4);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-Future<R> dispatch(const Process<T>* process,
-                   R (T::*method)(P1, P2, P3, P4),
-                   A1 a1, A2 a2, A3 a3, A4 a4);
-
-
-/**
- * Dispatches a method on a process and returns the future that
- * corresponds to the result of executing the method.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 first argument to pass to method
- * @param a2 second argument to pass to method
- * @param a3 third argument to pass to method
- * @param a4 fourth argument to pass to method
- * @param a5 fifth argument to pass to method
- * @return future corresponding to the result of executing the method
- */
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-Future<R> dispatch(const PID<T>& pid,
-                   R (T::*method)(P1, P2, P3, P4, P5),
-                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-Future<R> dispatch(const Process<T>& process,
-                   R (T::*method)(P1, P2, P3, P4, P5),
-                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-Future<R> dispatch(const Process<T>* process,
-                   R (T::*method)(P1, P2, P3, P4, P5),
-                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
-
-
-/**
- * Dispatches a method on a process and waits (on the underlying
- * future) for the result.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @return result of executing the method
- */
-template <typename R, typename T>
-R call(const PID<T>& pid,
-       Promise<R> (T::*method)());
-
-template <typename R, typename T>
-R call(const Process<T>& process,
-       Promise<R> (T::*method)());
-
-template <typename R, typename T>
-R call(const Process<T>* process,
-       Promise<R> (T::*method)());
-
-/**
- * Dispatches a method on a process and waits (on the underlying
- * future) for the result.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 argument to pass to method
- * @return result of executing the method
- */
-template <typename R, typename T,
-          typename P1, typename A1>
-R call(const PID<T>& pid,
-       Promise<R> (T::*method)(P1),
-       A1 a1);
-
-template <typename R, typename T,
-          typename P1, typename A1>
-R call(const Process<T>& process,
-       Promise<R> (T::*method)(P1),
-       A1 a1);
-
-template <typename R, typename T,
-          typename P1, typename A1>
-R call(const Process<T>* process,
-       Promise<R> (T::*method)(P1),
-       A1 a1);
-
-
-/**
- * Dispatches a method on a process and waits (on the underlying
- * future) for the result.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 first argument to pass to method
- * @param a2 second argument to pass to method
- * @return result of executing the method
- */
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-R call(const PID<T>& pid,
-       Promise<R> (T::*method)(P1, P2),
-       A1 a1, A2 a2);
-
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-R call(const Process<T>& process,
-       Promise<R> (T::*method)(P1, P2),
-       A1 a1, A2 a2);
-
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-R call(const Process<T>* process,
-       Promise<R> (T::*method)(P1, P2),
-       A1 a1, A2 a2);
-
-
-/**
- * Dispatches a method on a process and waits (on the underlying
- * future) for the result.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 first argument to pass to method
- * @param a2 second argument to pass to method
- * @param a3 second argument to pass to method
- * @return result of executing the method
- */
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-R call(const PID<T>& pid,
-       Promise<R> (T::*method)(P1, P2, P3),
-       A1 a1, A2 a2, A3 a3);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-R call(const Process<T>& process,
-       Promise<R> (T::*method)(P1, P2, P3),
-       A1 a1, A2 a2, A3 a3);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-R call(const Process<T>* process,
-       Promise<R> (T::*method)(P1, P2, P3),
-       A1 a1, A2 a2, A3 a3);
-
-
-/**
- * Dispatches a method on a process and waits (on the underlying
- * future) for the result.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 first argument to pass to method
- * @param a2 second argument to pass to method
- * @param a3 third argument to pass to method
- * @param a4 fourth argument to pass to method
- * @return result of executing the method
- */
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-R call(const PID<T>& pid,
-       Promise<R> (T::*method)(P1, P2, P3, P4),
-       A1 a1, A2 a2, A3 a3, A4 a4);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-R call(const Process<T>& process,
-       Promise<R> (T::*method)(P1, P2, P3, P4),
-       A1 a1, A2 a2, A3 a3, A4 a4);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-R call(const Process<T>* process,
-       Promise<R> (T::*method)(P1, P2, P3, P4),
-       A1 a1, A2 a2, A3 a3, A4 a4);
-
-
-/**
- * Dispatches a method on a process and waits (on the underlying
- * future) for the result.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 first argument to pass to method
- * @param a2 second argument to pass to method
- * @param a3 third argument to pass to method
- * @param a4 fourth argument to pass to method
- * @param a5 fifth argument to pass to method
- * @return result of executing the method
- */
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-R call(const PID<T>& pid,
-       Promise<R> (T::*method)(P1, P2, P3, P4, P5),
-       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-R call(const Process<T>& process,
-       Promise<R> (T::*method)(P1, P2, P3, P4, P5),
-       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-R call(const Process<T>* process,
-       Promise<R> (T::*method)(P1, P2, P3, P4, P5),
-       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
-
-
-/**
- * Dispatches a method on a process and waits (on the underlying
- * future) for the result.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @return result of executing the method
- */
-template <typename R, typename T>
-R call(const PID<T>& pid,
-       R (T::*method)());
-
-template <typename R, typename T>
-R call(const Process<T>& process,
-       R (T::*method)());
-
-template <typename R, typename T>
-R call(const Process<T>* process,
-       R (T::*method)());
-
-
-/**
- * Dispatches a method on a process and waits (on the underlying
- * future) for the result.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 argument to pass to method
- * @return result of executing the method
- */
-template <typename R, typename T,
-          typename P1, typename A1>
-R call(const PID<T>& pid,
-       R (T::*method)(P1),
-       A1 a1);
-
-template <typename R, typename T,
-          typename P1, typename A1>
-R call(const Process<T>& process,
-       R (T::*method)(P1),
-       A1 a1);
-
-template <typename R, typename T,
-          typename P1, typename A1>
-R call(const Process<T>* process,
-       R (T::*method)(P1),
-       A1 a1);
-
-
-/**
- * Dispatches a method on a process and waits (on the underlying
- * future) for the result.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 first argument to pass to method
- * @param a2 second argument to pass to method
- * @return result of executing the method
- */
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-R call(const PID<T>& pid,
-       R (T::*method)(P1, P2),
-       A1 a1, A2 a2);
-
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-R call(const Process<T>& process,
-       R (T::*method)(P1, P2),
-       A1 a1, A2 a2);
-
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-R call(const Process<T>* process,
-       R (T::*method)(P1, P2),
-       A1 a1, A2 a2);
-
-
-/**
- * Dispatches a method on a process and waits (on the underlying
- * future) for the result.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 first argument to pass to method
- * @param a2 second argument to pass to method
- * @param a3 second argument to pass to method
- * @return result of executing the method
- */
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-R call(const PID<T>& pid,
-       R (T::*method)(P1, P2, P3),
-       A1 a1, A2 a2, A3 a3);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-R call(const Process<T>& process,
-       R (T::*method)(P1, P2, P3),
-       A1 a1, A2 a2, A3 a3);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-R call(const Process<T>* process,
-       R (T::*method)(P1, P2, P3),
-       A1 a1, A2 a2, A3 a3);
-
-
-/**
- * Dispatches a method on a process and waits (on the underlying
- * future) for the result.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 first argument to pass to method
- * @param a2 second argument to pass to method
- * @param a3 third argument to pass to method
- * @param a4 fourth argument to pass to method
- * @return result of executing the method
- */
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-R call(const PID<T>& pid,
-       R (T::*method)(P1, P2, P3, P4),
-       A1 a1, A2 a2, A3 a3, A4 a4);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-R call(const Process<T>& process,
-       R (T::*method)(P1, P2, P3, P4),
-       A1 a1, A2 a2, A3 a3, A4 a4);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-R call(const Process<T>* process,
-       R (T::*method)(P1, P2, P3, P4),
-       A1 a1, A2 a2, A3 a3, A4 a4);
-
-
-/**
- * Dispatches a method on a process and waits (on the underlying
- * future) for the result.
- *
- * @param pid receiver of message
- * @param method method to invoke on instance
- * @param a1 first argument to pass to method
- * @param a2 second argument to pass to method
- * @param a3 third argument to pass to method
- * @param a4 fourth argument to pass to method
- * @param a5 fifth argument to pass to method
- * @return result of executing the method
- */
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-R call(const PID<T>& pid,
-       R (T::*method)(P1, P2, P3, P4, P5),
-       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-R call(const Process<T>& process,
-       R (T::*method)(P1, P2, P3, P4, P5),
-       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-R call(const Process<T>* process,
-       R (T::*method)(P1, P2, P3, P4, P5),
-       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
-
+// The dispatch mechanism enables you to "schedule" a method to get
+// invoked on a process. The result of that method invocation is
+// accessible via the future that is returned by the dispatch method
+// (note, however, that it might not be the _same_ future as the one
+// returned from the method, if the method even returns a future, see
+// below). Assuming some class 'Fibonacci' has a (visible) method
+// named 'compute' that takes an integer, N (and returns the Nth
+// fibonacci number) you might use dispatch like so:
+//
+// PID<Fibonacci> pid = spawn(new Fibonacci(), true); // Use the GC.
+// Future<int> f = dispatch(pid, &Fibonacci::compute, 10);
+//
+// Because the pid argument is "typed" we can ensure that methods are
+// only invoked on processes that are actually of that type. Providing
+// this mechanism for varying numbers of function types and arguments
+// requires support for variadic templates, slated to be released in
+// C++11. Until then, we use the Boost preprocessor macros to
+// accomplish the same thing (all be it less cleanly). See below for
+// those definitions.
+//
+// Dispatching is done via a level of indirection. The dispatch
+// routine itself creates a promise that is passed as an argument to a
+// partially applied 'dispatcher' function (defined below). The
+// dispatcher routines get passed to the actual process via an
+// internal routine called, not suprisingly, 'dispatch', defined
+// below:
 
 namespace internal {
 
+// The internal dispatch routine schedules a function to get invoked
+// within the context of the process associated with the specified pid
+// (first argument), unless that process is no longer valid (either
+// way this routine assumes ownership of the function and calls delete
+// on it). Note that this routine does not expect anything in
+// particular about the specified function (second argument). The
+// semantics are simple: the function gets applied/invoked with the
+// process as its first argument.
+void dispatch(const UPID& pid, std::tr1::function<void(ProcessBase*)>* f);
+
+
+// The magic of dispatch actually occurs within the dispatcher
+// routines. In particular, some of the dispatcher routines need to
+// wait for values and "associate" them with the future that got
+// returned from the original call to dispatch. Those association
+// functions are defined here:
+
 template <typename T>
-void __associate(const Future<T>& future, Promise<T> promise)
+void __associate(const Future<T>& from, std::tr1::shared_ptr<Promise<T> > to)
 {
   // The future associated with this promise is either pending
   // (because we haven't set it, failed it, or discarded it) or it's
   // discarded (because the receiver of the future has discarded it).
-  assert(promise.future().isPending() || promise.future().isDiscarded());
+  assert(to->future().isPending() || to->future().isDiscarded());
 
-  if (promise.future().isPending()) { // Avoid acquiring a lock.
-    if (future.isReady()) {
-      promise.set(future.get());
-    } else if (future.isFailed()) {
-      promise.fail(future.failure());
-    } else if (future.isDiscarded()) {
-      promise.future().discard();
+  if (to->future().isPending()) { // No-op if it's discarded.
+    if (from.isReady()) {
+      to->set(from.get());
+    } else if (from.isFailed()) {
+      to->fail(from.failure());
+    } else if (from.isDiscarded()) {
+      to->future().discard();
     }
   }
 }
 
 
 template <typename T>
-void associate(const Promise<T>& from, const Promise<T>& to)
+void associate(const Future<T>& from, std::tr1::shared_ptr<Promise<T> > to)
 {
-  std::tr1::function<void(const Future<T>&)> callback =
-    std::tr1::bind(__associate<T>, std::tr1::placeholders::_1, to);
-  from.future().onAny(callback);
+  from.onAny(std::tr1::bind(__associate<T>, std::tr1::placeholders::_1, to));
 }
 
 
+// Finally come the dispatcher functions (one for each return type:
+// void, future, value) which should complete the picture. Given the
+// process argument these routines downcast the process to the correct
+// subtype and invoke the thunk using the subtype as the argument
+// (receiver). Note that we must use dynamic_cast because we permit a
+// process to use multiple inheritance (e.g., to expose multiple
+// callback interfaces).
+
 template <typename T>
-void vdispatcher(ProcessBase* process,
-                 std::tr1::function<void(T*)> thunk)
+void vdispatcher(
+    ProcessBase* process,
+    std::tr1::shared_ptr<std::tr1::function<void(T*)> > thunk)
 {
   assert(process != NULL);
   T* t = dynamic_cast<T*>(process);
   assert(t != NULL);
-  thunk(t);
+  (*thunk)(t);
 }
 
 
 template <typename R, typename T>
-void pdispatcher(ProcessBase* process,
-                 std::tr1::function<Promise<R>(T*)> thunk,
-                 Promise<R> promise)
+void pdispatcher(
+    ProcessBase* process,
+    std::tr1::shared_ptr<std::tr1::function<Future<R>(T*)> > thunk,
+    std::tr1::shared_ptr<Promise<R> > promise)
 {
   assert(process != NULL);
   T* t = dynamic_cast<T*>(process);
   assert(t != NULL);
-  associate(thunk(t), promise);
+  associate((*thunk)(t), promise);
 }
 
 
 template <typename R, typename T>
-void dispatcher(ProcessBase* process,
-                std::tr1::function<R(T*)> thunk,
-                Promise<R> promise)
+void rdispatcher(
+    ProcessBase* process,
+    std::tr1::shared_ptr<std::tr1::function<R(T*)> > thunk,
+    std::tr1::shared_ptr<Promise<R> > promise)
 {
   assert(process != NULL);
   T* t = dynamic_cast<T*>(process);
   assert(t != NULL);
-  promise.set(thunk(t));
-}
-
-
-typedef std::tr1::function<void(ProcessBase*)> Dispatcher;
-
-// Dispatches a call on the specified process.
-void dispatch(const UPID& pid, Dispatcher* dispatcher);
-
-
-// Dispatches a call returning void on the specified process.
-template <typename T>
-void vdispatch(const UPID& pid,
-               const std::tr1::function<void(T*)>& thunk)
-{
-  Dispatcher* dispatcher = new Dispatcher(
-      std::tr1::bind(&internal::vdispatcher<T>,
-                     std::tr1::placeholders::_1,
-                     thunk));
-
-  dispatch(pid, dispatcher);
-}
-
-
-// Dispatches a call returning a Promise on the specified process.
-template <typename R, typename T>
-Future<R> pdispatch(const UPID& pid,
-                    const std::tr1::function<Promise<R>(T*)>& thunk)
-{
-  Promise<R> promise;
-
-  Dispatcher* dispatcher = new Dispatcher(
-      std::tr1::bind(&internal::pdispatcher<R, T>,
-                     std::tr1::placeholders::_1,
-                     thunk, promise));
-
-  dispatch(pid, dispatcher);
-
-  return promise.future();
-}
-
-
-// Dispatches a call for the specified process.
-template <typename R, typename T>
-Future<R> dispatch(const UPID& pid,
-                   const std::tr1::function<R(T*)>& thunk)
-{
-  Promise<R> promise;
-
-  Dispatcher* dispatcher = new Dispatcher(
-      std::tr1::bind(&internal::dispatcher<R, T>,
-                     std::tr1::placeholders::_1,
-                     thunk, promise));
-
-  dispatch(pid, dispatcher);
-
-  return promise.future();
+  promise->set((*thunk)(t));
 }
 
 } // namespace internal {
 
 
-/////////////////////////////////
-// Returning void with 0 args. //
-/////////////////////////////////
+// Okay, now for the definition of the dispatch routines
+// themselves. For each routine we provide the version in C++11 using
+// variadic templates so the reader can see what the Boost
+// preprocessor macros are effectively providing. Using C++11 closures
+// would shorten these definitions even more.
+//
+// First, definitions of dispatch for methods returning void:
+//
+// template <typename T, typename ...P>
+// void dispatch(
+//     const PID<T>& pid,
+//     void (T::*method)(P...),
+//     P... p)
+// {
+//   std::tr1::shared_ptr<std::tr1::function<void(T*)> > thunk(
+//       new std::tr1::function<void(T*)>(
+//           std::tr1::bind(method,
+//                          std::tr1::placeholders::_1,
+//                          std::forward<P>(p)...)));
+//
+//   std::tr1::function<void(ProcessBase*)>* dispatcher =
+//     new std::tr1::function<void(ProcessBase*)>(
+//         std::tr1::bind(&internal::vdispatcher<T>,
+//                        std::tr1::placeholders::_1,
+//                        thunk));
+//
+//   internal::dispatch(pid, dispatcher);
+// }
 
 template <typename T>
-void dispatch(const PID<T>& pid,
-              void (T::*method)())
-{
-  std::tr1::function<void(T*)> thunk =
-    std::tr1::bind(method, std::tr1::placeholders::_1);
+void dispatch(
+    const PID<T>& pid,
+    void (T::*method)(void))
+{
+  std::tr1::shared_ptr<std::tr1::function<void(T*)> > thunk(
+      new std::tr1::function<void(T*)>(
+          std::tr1::bind(method, std::tr1::placeholders::_1)));
+
+  std::tr1::function<void(ProcessBase*)>* dispatcher =
+    new std::tr1::function<void(ProcessBase*)>(
+        std::tr1::bind(&internal::vdispatcher<T>,
+                       std::tr1::placeholders::_1,
+                       thunk));
 
-  internal::vdispatch(pid, thunk);
+  internal::dispatch(pid, dispatcher);
 }
 
-
 template <typename T>
-void dispatch(const Process<T>& process,
-              void (T::*method)())
+void dispatch(
+    const Process<T>& process,
+    void (T::*method)(void))
 {
   dispatch(process.self(), method);
 }
 
-
 template <typename T>
-void dispatch(const Process<T>* process,
-              void (T::*method)())
+void dispatch(
+    const Process<T>* process,
+    void (T::*method)(void))
 {
   dispatch(process->self(), method);
 }
 
+#define TEMPLATE(Z, N, DATA)                                            \
+  template <typename T,                                                 \
+            ENUM_PARAMS(N, typename P),                                 \
+            ENUM_PARAMS(N, typename A)>                                 \
+  void dispatch(                                                        \
+      const PID<T>& pid,                                                \
+      void (T::*method)(ENUM_PARAMS(N, P)),                             \
+      ENUM_BINARY_PARAMS(N, A, a))                                      \
+  {                                                                     \
+    std::tr1::shared_ptr<std::tr1::function<void(T*)> > thunk(          \
+        new std::tr1::function<void(T*)>(                               \
+            std::tr1::bind(method,                                      \
+                           std::tr1::placeholders::_1,                  \
+                           ENUM_PARAMS(N, a))));                        \
+                                                                        \
+    std::tr1::function<void(ProcessBase*)>* dispatcher =                \
+      new std::tr1::function<void(ProcessBase*)>(                       \
+          std::tr1::bind(&internal::vdispatcher<T>,                     \
+                         std::tr1::placeholders::_1,                    \
+                         thunk));                                       \
+                                                                        \
+    internal::dispatch(pid, dispatcher);                                \
+  }                                                                     \
+                                                                        \
+  template <typename T,                                                 \
+            ENUM_PARAMS(N, typename P),                                 \
+            ENUM_PARAMS(N, typename A)>                                 \
+  void dispatch(                                                        \
+      const Process<T>& process,                                        \
+      void (T::*method)(ENUM_PARAMS(N, P)),                             \
+      ENUM_BINARY_PARAMS(N, A, a))                                      \
+  {                                                                     \
+    dispatch(process.self(), method, ENUM_PARAMS(N, a));                \
+  }                                                                     \
+                                                                        \
+  template <typename T,                                                 \
+            ENUM_PARAMS(N, typename P),                                 \
+            ENUM_PARAMS(N, typename A)>                                 \
+  void dispatch(                                                        \
+      const Process<T>* process,                                        \
+      void (T::*method)(ENUM_PARAMS(N, P)),                             \
+      ENUM_BINARY_PARAMS(N, A, a))                                      \
+  {                                                                     \
+    dispatch(process->self(), method, ENUM_PARAMS(N, a));               \
+  }
 
-/////////////////////////////////
-// Returning void with 1 args. //
-/////////////////////////////////
-
-template <typename T, typename P1, typename A1>
-void dispatch(const PID<T>& pid,
-              void (T::*method)(P1),
-              A1 a1)
-{
-  std::tr1::function<void(T*)> thunk =
-    std::tr1::bind(method, std::tr1::placeholders::_1, a1);
-
-  internal::vdispatch(pid, thunk);
-}
-
-
-template <typename T, typename P1, typename A1>
-void dispatch(const Process<T>& process,
-              void (T::*method)(P1),
-              A1 a1)
-{
-  dispatch(process.self(), method, a1);
-}
-
-
-template <typename T, typename P1, typename A1>
-void dispatch(const Process<T>* process,
-              void (T::*method)(P1),
-              A1 a1)
-{
-  dispatch(process->self(), method, a1);
-}
-
-
-/////////////////////////////////
-// Returning void with 2 args. //
-/////////////////////////////////
-
-template <typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-void dispatch(const PID<T>& pid,
-              void (T::*method)(P1, P2),
-              A1 a1, A2 a2)
-{
-  std::tr1::function<void(T*)> thunk =
-    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2);
-
-  internal::vdispatch(pid, thunk);
-}
-
-
-template <typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-void dispatch(const Process<T>& process,
-              void (T::*method)(P1, P2),
-              A1 a1, A2 a2)
-{
-  dispatch(process.self(), method, a1, a2);
-}
-
-
-template <typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-void dispatch(const Process<T>* process,
-              void (T::*method)(P1, P2),
-              A1 a1, A2 a2)
-{
-  dispatch(process->self(), method, a1, a2);
-}
-
-
-/////////////////////////////////
-// Returning void with 3 args. //
-/////////////////////////////////
-
-template <typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-void dispatch(const PID<T>& pid,
-              void (T::*method)(P1, P2, P3),
-              A1 a1, A2 a2, A3 a3)
-{
-  std::tr1::function<void(T*)> thunk =
-    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2, a3);
-
-  internal::vdispatch(pid, thunk);
-}
-
-
-template <typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-void dispatch(const Process<T>& process,
-              void (T::*method)(P1, P2, P3),
-              A1 a1, A2 a2, A3 a3)
-{
-  dispatch(process.self(), method, a1, a2, a3);
-}
-
-
-template <typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-void dispatch(const Process<T>* process,
-              void (T::*method)(P1, P2, P3),
-              A1 a1, A2 a2, A3 a3)
-{
-  dispatch(process->self(), method, a1, a2, a3);
-}
-
-
-/////////////////////////////////
-// Returning void with 4 args. //
-/////////////////////////////////
-
-template <typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-void dispatch(const PID<T>& pid,
-              void (T::*method)(P1, P2, P3, P4),
-              A1 a1, A2 a2, A3 a3, A4 a4)
-{
-  std::tr1::function<void(T*)> thunk =
-    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2, a3, a4);
-
-  internal::vdispatch(pid, thunk);
-}
-
-
-template <typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-void dispatch(const Process<T>& process,
-              void (T::*method)(P1, P2, P3, P4),
-              A1 a1, A2 a2, A3 a3, A4 a4)
-{
-  dispatch(process.self(), method, a1, a2, a3, a4);
-}
-
-
-template <typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-void dispatch(const Process<T>* process,
-              void (T::*method)(P1, P2, P3, P4),
-              A1 a1, A2 a2, A3 a3, A4 a4)
-{
-  dispatch(process->self(), method, a1, a2, a3, a4);
-}
-
-
-/////////////////////////////////
-// Returning void with 5 args. //
-/////////////////////////////////
-
-template <typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-void dispatch(const PID<T>& pid,
-              void (T::*method)(P1, P2, P3, P4, P5),
-              A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
-{
-  std::tr1::function<void(T*)> thunk =
-    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2, a3, a4, a5);
-
-  internal::vdispatch(pid, thunk);
-}
-
-
-template <typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-void dispatch(const Process<T>& process,
-              void (T::*method)(P1, P2, P3, P4, P5),
-              A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
-{
-  dispatch(process.self(), method, a1, a2, a3, a4, a5);
-}
-
-
-template <typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-void dispatch(const Process<T>* process,
-              void (T::*method)(P1, P2, P3, P4, P5),
-              A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
-{
-  dispatch(process->self(), method, a1, a2, a3, a4, a5);
-}
-
-
-///////////////////////////////////////
-// Returning Promise<R> with 0 args. //
-///////////////////////////////////////
+  REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
 
-template <typename R, typename T>
-Future<R> dispatch(const PID<T>& pid,
-                   Promise<R> (T::*method)())
-{
-  std::tr1::function<Promise<R>(T*)> thunk =
-    std::tr1::bind(method, std::tr1::placeholders::_1);
 
-  return internal::pdispatch(pid, thunk);
+// Next, definitions of methods returning a future:
+//
+// template <typename R, typename T, typename ...P>
+// Future<R> dispatch(
+//     const PID<T>& pid,
+//     Future<R> (T::*method)(P...),
+//     P... p)
+// {
+//   std::tr1::shared_ptr<std::tr1::function<Future<R>(T*)> > thunk(
+//       new std::tr1::function<Future<R>(T*)>(
+//           std::tr1::bind(method,
+//                          std::tr1::placeholders::_1,
+//                          std::forward<P>(p)...)));
+//
+//   std::tr1::shared_ptr<Promise<R> > promise(new Promise<R>());
+//   Future<R> future = promise->future();
+//
+//   std::tr1::function<void(ProcessBase*)>* dispatcher =
+//     new std::tr1::function<void(ProcessBase*)>(
+//         std::tr1::bind(&internal::pdispatcher<R, T>,
+//                        std::tr1::placeholders::_1,
+//                        thunk, promise));
+//
+//   internal::dispatch(pid, dispatcher);
+//
+//   return future;
+// }
+
+template <typename R, typename T>
+Future<R> dispatch(
+    const PID<T>& pid,
+    Future<R> (T::*method)(void))
+{
+  std::tr1::shared_ptr<std::tr1::function<Future<R>(T*)> > thunk(
+      new std::tr1::function<Future<R>(T*)>(
+          std::tr1::bind(method, std::tr1::placeholders::_1)));
+
+  std::tr1::shared_ptr<Promise<R> > promise(new Promise<R>());
+  Future<R> future = promise->future();
+
+  std::tr1::function<void(ProcessBase*)>* dispatcher =
+    new std::tr1::function<void(ProcessBase*)>(
+        std::tr1::bind(&internal::pdispatcher<R, T>,
+                       std::tr1::placeholders::_1,
+                       thunk, promise));
+
+  internal::dispatch(pid, dispatcher);
+
+  return future;
 }
 
-
 template <typename R, typename T>
-Future<R> dispatch(const Process<T>& process,
-                   Promise<R> (T::*method)())
+Future<R> dispatch(
+    const Process<T>& process,
+    Future<R> (T::*method)(void))
 {
   return dispatch(process.self(), method);
 }
 
-
 template <typename R, typename T>
-Future<R> dispatch(const Process<T>* process,
-                   Promise<R> (T::*method)())
+Future<R> dispatch(
+    const Process<T>* process,
+    Future<R> (T::*method)(void))
 {
   return dispatch(process->self(), method);
 }
 
+#define TEMPLATE(Z, N, DATA)                                            \
+  template <typename R,                                                 \
+            typename T,                                                 \
+            ENUM_PARAMS(N, typename P),                                 \
+            ENUM_PARAMS(N, typename A)>                                 \
+  Future<R> dispatch(                                                   \
+      const PID<T>& pid,                                                \
+      Future<R> (T::*method)(ENUM_PARAMS(N, P)),                        \
+      ENUM_BINARY_PARAMS(N, A, a))                                      \
+  {                                                                     \
+    std::tr1::shared_ptr<std::tr1::function<Future<R>(T*)> > thunk(     \
+        new std::tr1::function<Future<R>(T*)>(                          \
+            std::tr1::bind(method,                                      \
+                           std::tr1::placeholders::_1,                  \
+                           ENUM_PARAMS(N, a))));                        \
+                                                                        \
+    std::tr1::shared_ptr<Promise<R> > promise(new Promise<R>());        \
+    Future<R> future = promise->future();                               \
+                                                                        \
+    std::tr1::function<void(ProcessBase*)>* dispatcher =                \
+      new std::tr1::function<void(ProcessBase*)>(                       \
+          std::tr1::bind(&internal::pdispatcher<R, T>,                  \
+                         std::tr1::placeholders::_1,                    \
+                         thunk, promise));                              \
+                                                                        \
+    internal::dispatch(pid, dispatcher);                                \
+                                                                        \
+    return future;                                                      \
+  }                                                                     \
+                                                                        \
+  template <typename R,                                                 \
+            typename T,                                                 \
+            ENUM_PARAMS(N, typename P),                                 \
+            ENUM_PARAMS(N, typename A)>                                 \
+  Future<R> dispatch(                                                   \
+      const Process<T>& process,                                        \
+      Future<R> (T::*method)(ENUM_PARAMS(N, P)),                        \
+      ENUM_BINARY_PARAMS(N, A, a))                                      \
+  {                                                                     \
+    return dispatch(process.self(), method, ENUM_PARAMS(N, a));         \
+  }                                                                     \
+                                                                        \
+  template <typename R,                                                 \
+            typename T,                                                 \
+            ENUM_PARAMS(N, typename P),                                 \
+            ENUM_PARAMS(N, typename A)>                                 \
+  Future<R> dispatch(                                                   \
+      const Process<T>* process,                                        \
+      Future<R> (T::*method)(ENUM_PARAMS(N, P)),                        \
+      ENUM_BINARY_PARAMS(N, A, a))                                      \
+  {                                                                     \
+    return dispatch(process->self(), method, ENUM_PARAMS(N, a));        \
+  }
 
-///////////////////////////////////////
-// Returning Promise<R> with 1 args. //
-///////////////////////////////////////
-
-template <typename R, typename T, typename P1, typename A1>
-Future<R> dispatch(const PID<T>& pid,
-                   Promise<R> (T::*method)(P1),
-                   A1 a1)
-{
-  std::tr1::function<Promise<R>(T*)> thunk =
-    std::tr1::bind(method, std::tr1::placeholders::_1, a1);
-
-  return internal::pdispatch(pid, thunk);
-}
-
-
-template <typename R, typename T,
-          typename P1, typename A1>
-Future<R> dispatch(const Process<T>& process,
-                   Promise<R> (T::*method)(P1),
-                   A1 a1)
-{
-  return dispatch(process.self(), method, a1);
-}
-
-
-template <typename R, typename T,
-          typename P1, typename A1>
-Future<R> dispatch(const Process<T>* process,
-                   Promise<R> (T::*method)(P1),
-                   A1 a1)
-{
-  return dispatch(process->self(), method, a1);
-}
-
-
-///////////////////////////////////////
-// Returning Promise<R> with 2 args. //
-///////////////////////////////////////
-
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-Future<R> dispatch(const PID<T>& pid,
-                   Promise<R> (T::*method)(P1, P2),
-                   A1 a1, A2 a2)
-{
-  std::tr1::function<Promise<R>(T*)> thunk =
-    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2);
-
-  return internal::pdispatch(pid, thunk);
-}
-
-
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-Future<R> dispatch(const Process<T>& process,
-                   Promise<R> (T::*method)(P1, P2),
-                   A1 a1, A2 a2)
-{
-  return dispatch(process.self(), method, a1, a2);
-}
-
-
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-Future<R> dispatch(const Process<T>* process,
-                   Promise<R> (T::*method)(P1, P2),
-                   A1 a1, A2 a2)
-{
-  return dispatch(process->self(), method, a1, a2);
-}
-
-
-///////////////////////////////////////
-// Returning Promise<R> with 3 args. //
-///////////////////////////////////////
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-Future<R> dispatch(const PID<T>& pid,
-                   Promise<R> (T::*method)(P1, P2, P3),
-                   A1 a1, A2 a2, A3 a3)
-{
-  std::tr1::function<Promise<R>(T*)> thunk =
-    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2, a3);
-
-  return internal::pdispatch(pid, thunk);
-}
-
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-Future<R> dispatch(const Process<T>& process,
-                   Promise<R> (T::*method)(P1, P2, P3),
-                   A1 a1, A2 a2, A3 a3)
-{
-  return dispatch(process.self(), method, a1, a2, a3);
-}
-
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-Future<R> dispatch(const Process<T>* process,
-                   Promise<R> (T::*method)(P1, P2, P3),
-                   A1 a1, A2 a2, A3 a3)
-{
-  return dispatch(process->self(), method, a1, a2, a3);
-}
-
-
-///////////////////////////////////////
-// Returning Promise<R> with 4 args. //
-///////////////////////////////////////
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-Future<R> dispatch(const PID<T>& pid,
-                   Promise<R> (T::*method)(P1, P2, P3, P4),
-                   A1 a1, A2 a2, A3 a3, A4 a4)
-{
-  std::tr1::function<Promise<R>(T*)> thunk =
-    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2, a3, a4);
-
-  return internal::pdispatch(pid, thunk);
-}
-
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-Future<R> dispatch(const Process<T>& process,
-                   Promise<R> (T::*method)(P1, P2, P3, P4),
-                   A1 a1, A2 a2, A3 a3, A4 a4)
-{
-  return dispatch(process.self(), method, a1, a2, a3, a4);
-}
-
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-Future<R> dispatch(const Process<T>* process,
-                   Promise<R> (T::*method)(P1, P2, P3, P4),
-                   A1 a1, A2 a2, A3 a3, A4 a4)
-{
-  return dispatch(process->self(), method, a1, a2, a3, a4);
-}
-
-
-///////////////////////////////////////
-// Returning Promise<R> with 5 args. //
-///////////////////////////////////////
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-Future<R> dispatch(const PID<T>& pid,
-                   Promise<R> (T::*method)(P1, P2, P3, P4, P5),
-                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
-{
-  std::tr1::function<Promise<R>(T*)> thunk =
-    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2, a3, a4, a5);
-
-  return internal::pdispatch(pid, thunk);
-}
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-Future<R> dispatch(const Process<T>& process,
-                   Promise<R> (T::*method)(P1, P2, P3, P4, P5),
-                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
-{
-  return dispatch(process.self(), method, a1, a2, a3, a4, a5);
-}
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-Future<R> dispatch(const Process<T>* process,
-                   Promise<R> (T::*method)(P1, P2, P3, P4, P5),
-                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
-{
-  return dispatch(process->self(), method, a1, a2, a3, a4, a5);
-}
-
+  REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
 
-//////////////////////////////
-// Returning R with 0 args. //
-//////////////////////////////
 
-template <typename R, typename T>
-Future<R> dispatch(const PID<T>& pid,
-                   R (T::*method)())
-{
-  std::tr1::function<R(T*)> thunk =
-    std::tr1::bind(method, std::tr1::placeholders::_1);
-
-  return internal::dispatch(pid, thunk);
+// Next, definitions of methods returning a value.
+//
+// template <typename R, typename T, typename ...P>
+// Future<R> dispatch(
+//     const PID<T>& pid,
+//     R (T::*method)(P...),
+//     P... p)
+// {
+//   std::tr1::shared_ptr<std::tr1::function<R(T*)> > thunk(
+//       new std::tr1::function<R(T*)>(
+//           std::tr1::bind(method,
+//                          std::tr1::placeholders::_1,
+//                          std::forward<P>(p)...)));
+//
+//   std::tr1::shared_ptr<Promise<R> > promise(new Promise<R>());
+//   Future<R> future = promise->future();
+//
+//   std::tr1::function<void(ProcessBase*)>* dispatcher =
+//     new std::tr1::function<void(ProcessBase*)>(
+//         std::tr1::bind(&internal::rdispatcher<R, T>,
+//                        std::tr1::placeholders::_1,
+//                        thunk, promise));
+//
+//   internal::dispatch(pid, dispatcher);
+//
+//   return future;
+// }
+
+template <typename R, typename T>
+Future<R> dispatch(
+    const PID<T>& pid,
+    R (T::*method)(void))
+{
+  std::tr1::shared_ptr<std::tr1::function<R(T*)> > thunk(
+      new std::tr1::function<R(T*)>(
+          std::tr1::bind(method, std::tr1::placeholders::_1)));
+
+  std::tr1::shared_ptr<Promise<R> > promise(new Promise<R>());
+  Future<R> future = promise->future();
+
+  std::tr1::function<void(ProcessBase*)>* dispatcher =
+    new std::tr1::function<void(ProcessBase*)>(
+        std::tr1::bind(&internal::rdispatcher<R, T>,
+                       std::tr1::placeholders::_1,
+                       thunk, promise));
+
+  internal::dispatch(pid, dispatcher);
+
+  return future;
 }
 
 template <typename R, typename T>
-Future<R> dispatch(const Process<T>& process,
-                   R (T::*method)())
+Future<R> dispatch(
+    const Process<T>& process,
+    R (T::*method)(void))
 {
   return dispatch(process.self(), method);
 }
 
 template <typename R, typename T>
-Future<R> dispatch(const Process<T>* process,
-                   R (T::*method)())
+Future<R> dispatch(
+    const Process<T>* process,
+    R (T::*method)(void))
 {
   return dispatch(process->self(), method);
 }
 
+#define TEMPLATE(Z, N, DATA)                                            \
+  template <typename R,                                                 \
+            typename T,                                                 \
+            ENUM_PARAMS(N, typename P),                                 \
+            ENUM_PARAMS(N, typename A)>                                 \
+  Future<R> dispatch(                                                   \
+      const PID<T>& pid,                                                \
+      R (T::*method)(ENUM_PARAMS(N, P)),                                \
+      ENUM_BINARY_PARAMS(N, A, a))                                      \
+  {                                                                     \
+    std::tr1::shared_ptr<std::tr1::function<R(T*)> > thunk(             \
+        new std::tr1::function<R(T*)>(                                  \
+            std::tr1::bind(method,                                      \
+                           std::tr1::placeholders::_1,                  \
+                           ENUM_PARAMS(N, a))));                        \
+                                                                        \
+    std::tr1::shared_ptr<Promise<R> > promise(new Promise<R>());        \
+    Future<R> future = promise->future();                               \
+                                                                        \
+    std::tr1::function<void(ProcessBase*)>* dispatcher =                \
+      new std::tr1::function<void(ProcessBase*)>(                       \
+          std::tr1::bind(&internal::rdispatcher<R, T>,                  \
+                         std::tr1::placeholders::_1,                    \
+                         thunk, promise));                              \
+                                                                        \
+    internal::dispatch(pid, dispatcher);                                \
+                                                                        \
+    return future;                                                      \
+  }                                                                     \
+                                                                        \
+  template <typename R,                                                 \
+            typename T,                                                 \
+            ENUM_PARAMS(N, typename P),                                 \
+            ENUM_PARAMS(N, typename A)>                                 \
+  Future<R> dispatch(                                                   \
+      const Process<T>& process,                                        \
+      R (T::*method)(ENUM_PARAMS(N, P)),                                \
+      ENUM_BINARY_PARAMS(N, A, a))                                      \
+  {                                                                     \
+    return dispatch(process.self(), method, ENUM_PARAMS(N, a));         \
+  }                                                                     \
+                                                                        \
+  template <typename R,                                                 \
+            typename T,                                                 \
+            ENUM_PARAMS(N, typename P),                                 \
+            ENUM_PARAMS(N, typename A)>                                 \
+  Future<R> dispatch(                                                   \
+      const Process<T>* process,                                        \
+      R (T::*method)(ENUM_PARAMS(N, P)),                                \
+      ENUM_BINARY_PARAMS(N, A, a))                                      \
+  {                                                                     \
+    return dispatch(process->self(), method, ENUM_PARAMS(N, a));        \
+  }
 
-//////////////////////////////
-// Returning R with 1 args. //
-//////////////////////////////
-
-template <typename R, typename T, typename P1, typename A1>
-Future<R> dispatch(const PID<T>& pid,
-                   R (T::*method)(P1),
-                   A1 a1)
-{
-  std::tr1::function<R(T*)> thunk =
-    std::tr1::bind(method, std::tr1::placeholders::_1, a1);
-
-  return internal::dispatch(pid, thunk);
-}
-
-template <typename R, typename T,
-          typename P1, typename A1>
-Future<R> dispatch(const Process<T>& process,
-                   R (T::*method)(P1),
-                   A1 a1)
-{
-  return dispatch(process.self(), method, a1);
-}
-
-template <typename R, typename T, typename P1, typename A1>
-Future<R> dispatch(const Process<T>* process,
-                   R (T::*method)(P1),
-                   A1 a1)
-{
-  return dispatch(process->self(), method, a1);
-}
-
-
-//////////////////////////////
-// Returning R with 2 args. //
-//////////////////////////////
-
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-Future<R> dispatch(const PID<T>& pid,
-                   R (T::*method)(P1, P2),
-                   A1 a1, A2 a2)
-{
-  std::tr1::function<R(T*)> thunk =
-    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2);
-
-  return internal::dispatch(pid, thunk);
-}
-
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-Future<R> dispatch(const Process<T>& process,
-                   R (T::*method)(P1, P2),
-                   A1 a1, A2 a2)
-{
-  return dispatch(process.self(), method, a1, a2);
-}
-
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-Future<R> dispatch(const Process<T>* process,
-                   R (T::*method)(P1, P2),
-                   A1 a1, A2 a2)
-{
-  return dispatch(process->self(), method, a1, a2);
-}
-
-
-//////////////////////////////
-// Returning R with 3 args. //
-//////////////////////////////
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-Future<R> dispatch(const PID<T>& pid,
-                   R (T::*method)(P1, P2, P3),
-                   A1 a1, A2 a2, A3 a3)
-{
-  std::tr1::function<R(T*)> thunk =
-    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2, a3);
-
-  return internal::dispatch(pid, thunk);
-}
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-Future<R> dispatch(const Process<T>& process,
-                   R (T::*method)(P1, P2, P3),
-                   A1 a1, A2 a2, A3 a3)
-{
-  return dispatch(process.self(), method, a1, a2, a3);
-}
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-Future<R> dispatch(const Process<T>* process,
-                   R (T::*method)(P1, P2, P3),
-                   A1 a1, A2 a2, A3 a3)
-{
-  return dispatch(process->self(), method, a1, a2, a3);
-}
-
-
-//////////////////////////////
-// Returning R with 4 args. //
-//////////////////////////////
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-Future<R> dispatch(const PID<T>& pid,
-                   R (T::*method)(P1, P2, P3, P4),
-                   A1 a1, A2 a2, A3 a3, A4 a4)
-{
-  std::tr1::function<R(T*)> thunk =
-    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2, a3, a4);
-
-  return internal::dispatch(pid, thunk);
-}
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-Future<R> dispatch(const Process<T>& process,
-                   R (T::*method)(P1, P2, P3, P4),
-                   A1 a1, A2 a2, A3 a3, A4 a4)
-{
-  return dispatch(process.self(), method, a2, a2, a3, a4);
-}
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-Future<R> dispatch(const Process<T>* process,
-                   R (T::*method)(P1, P2, P3, P4),
-                   A1 a1, A2 a2, A3 a3, A4 a4)
-{
-  return dispatch(process->self(), method, a2, a2, a3, a4);
-}
-
-
-//////////////////////////////
-// Returning R with 5 args. //
-//////////////////////////////
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-Future<R> dispatch(const PID<T>& pid,
-                   R (T::*method)(P1, P2, P3, P4, P5),
-                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
-{
-  std::tr1::function<R(T*)> thunk =
-    std::tr1::bind(method, std::tr1::placeholders::_1, a1, a2, a3, a4, a5);
-
-  return internal::dispatch(pid, thunk);
-}
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-Future<R> dispatch(const Process<T>& process,
-                   R (T::*method)(P1, P2, P3, P4, P5),
-                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
-{
-  return dispatch(process.self(), method, a1, a2, a3, a4, a5);
-}
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-Future<R> dispatch(const Process<T>* process,
-                   R (T::*method)(P1, P2, P3, P4, P5),
-                   A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
-{
-  return dispatch(process->self(), method, a1, a2, a3, a4, a5);
-}
-
-
-/////////////////////////////////////////////
-// Returning R via Promise<R> with 0 args. //
-/////////////////////////////////////////////
-
-template <typename R, typename T>
-R call(const PID<T>& pid,
-       Promise<R> (T::*method)())
-{
-  return dispatch(pid, method).get();
-}
-
-template <typename R, typename T>
-R call(const Process<T>& process,
-       Promise<R> (T::*method)())
-{
-  return call(process.self(), method);
-}
-
-
-template <typename R, typename T>
-R call(const Process<T>* process,
-       Promise<R> (T::*method)())
-{
-  return call(process->self(), method);
-}
-
-
-/////////////////////////////////////////////
-// Returning R via Promise<R> with 1 args. //
-/////////////////////////////////////////////
-
-template <typename R, typename T, typename P1, typename A1>
-R call(const PID<T>& pid,
-       Promise<R> (T::*method)(P1), A1 a1)
-{
-  return dispatch(pid, method, a1).get();
-}
-
-template <typename R, typename T,
-          typename P1, typename A1>
-R call(const Process<T>& process,
-       Promise<R> (T::*method)(P1),
-       A1 a1)
-{
-  return call(process.self(), method, a1);
-}
-
-template <typename R, typename T,
-          typename P1, typename A1>
-R call(const Process<T>* process,
-       Promise<R> (T::*method)(P1),
-       A1 a1)
-{
-  return call(process->self(), method, a1);
-}
-
-
-/////////////////////////////////////////////
-// Returning R via Promise<R> with 2 args. //
-/////////////////////////////////////////////
-
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-R call(const PID<T>& pid,
-       Promise<R> (T::*method)(P1, P2), A1 a1, A2 a2)
-{
-  return dispatch(pid, method, a1, a2).get();
-}
-
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-R call(const Process<T>& process,
-       Promise<R> (T::*method)(P1, P2),
-       A1 a1, A2 a2)
-{
-  return call(process.self(), method, a1, a2);
-}
-
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-R call(const Process<T>* process,
-       Promise<R> (T::*method)(P1, P2),
-       A1 a1, A2 a2)
-{
-  return call(process->self(), method, a1, a2);
-}
-
-
-
-/////////////////////////////////////////////
-// Returning R via Promise<R> with 3 args. //
-/////////////////////////////////////////////
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-R call(const PID<T>& pid,
-       Promise<R> (T::*method)(P1, P2, P3),
-       A1 a1, A2 a2, A3 a3)
-{
-  return dispatch(pid, method, a1, a2, a3).get();
-}
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-R call(const Process<T>& process,
-       Promise<R> (T::*method)(P1, P2, P3),
-       A1 a1, A2 a2, A3 a3)
-{
-  return call(process.self(), method, a1, a2, a3);
-}
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-R call(const Process<T>* process,
-       Promise<R> (T::*method)(P1, P2, P3),
-       A1 a1, A2 a2, A3 a3)
-{
-  return call(process->self(), method, a1, a2, a3);
-}
-
-
-/////////////////////////////////////////////
-// Returning R via Promise<R> with 4 args. //
-/////////////////////////////////////////////
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-R call(const PID<T>& pid,
-       Promise<R> (T::*method)(P1, P2, P3, P4),
-       A1 a1, A2 a2, A3 a3, A4 a4)
-{
-  return dispatch(pid, method, a1, a2, a3, a4).get();
-}
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-R call(const Process<T>& process,
-       Promise<R> (T::*method)(P1, P2, P3, P4),
-       A1 a1, A2 a2, A3 a3, A4 a4)
-{
-  return call(process.self(), method, a1, a2, a3, a4);
-}
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-R call(const Process<T>* process,
-       Promise<R> (T::*method)(P1, P2, P3, P4),
-       A1 a1, A2 a2, A3 a3, A4 a4)
-{
-  return call(process->self(), method, a1, a2, a3, a4);
-}
-
-
-/////////////////////////////////////////////
-// Returning R via Promise<R> with 5 args. //
-/////////////////////////////////////////////
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-R call(const PID<T>& pid,
-       Promise<R> (T::*method)(P1, P2, P3, P4, P5),
-       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
-{
-  return dispatch(pid, method, a1, a2, a3, a4, a5).get();
-}
-
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-R call(const Process<T>& process,
-       Promise<R> (T::*method)(P1, P2, P3, P4, P5),
-       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
-{
-  return call(process.self(), method, a1, a2, a3, a4, a5);
-}
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-R call(const Process<T>* process,
-       Promise<R> (T::*method)(P1, P2, P3, P4, P5),
-       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
-{
-  return call(process->self(), method, a1, a2, a3, a4, a5);
-}
-
-
-////////////////////////////////////
-// Returning R via R with 0 args. //
-////////////////////////////////////
-
-template <typename R, typename T>
-R call(const PID<T>& pid,
-       R (T::*method)())
-{
-  return dispatch(pid, method).get();
-}
-
-template <typename R, typename T>
-R call(const Process<T>& process,
-       R (T::*method)())
-{
-  return call(process.self(), method);
-}
-
-template <typename R, typename T>
-R call(const Process<T>* process,
-       R (T::*method)())
-{
-  return call(process->self(), method);
-}
-
-
-////////////////////////////////////
-// Returning R via R with 1 args. //
-////////////////////////////////////
-
-template <typename R, typename T,
-          typename P1, typename A1>
-R call(const PID<T>& pid,
-       R (T::*method)(P1),
-       A1 a1)
-{
-  return dispatch(pid, method, a1).get();
-}
-
-template <typename R, typename T,
-          typename P1, typename A1>
-R call(const Process<T>& process,
-       R (T::*method)(P1),
-       A1 a1)
-{
-  return call(process.self(), method, a1);
-}
-
-template <typename R, typename T,
-          typename P1, typename A1>
-R call(const Process<T>* process,
-       R (T::*method)(P1),
-       A1 a1)
-{
-  return call(process->self(), method, a1);
-}
-
-
-////////////////////////////////////
-// Returning R via R with 2 args. //
-////////////////////////////////////
-
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-R call(const PID<T>& pid,
-       R (T::*method)(P1, P2),
-       A1 a1, A2 a2)
-{
-  return dispatch(pid, method, a1, a2).get();
-}
-
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-R call(const Process<T>& process,
-       R (T::*method)(P1, P2),
-       A1 a1, A2 a2)
-{
-  return call(process.self(), method, a1, a2);
-}
-
-template <typename R, typename T,
-          typename P1, typename P2,
-          typename A1, typename A2>
-R call(const Process<T>* process,
-       R (T::*method)(P1, P2),
-       A1 a1, A2 a2)
-{
-  return call(process->self(), method, a1, a2);
-}
-
-
-////////////////////////////////////
-// Returning R via R with 3 args. //
-////////////////////////////////////
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-R call(const PID<T>& pid,
-       R (T::*method)(P1, P2, P3),
-       A1 a1, A2 a2, A3 a3)
-{
-  return dispatch(pid, method, a1, a2, a3).get();
-}
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-R call(const Process<T>& process,
-       R (T::*method)(P1, P2, P3),
-       A1 a1, A2 a2, A3 a3)
-{
-  return call (process.self(), method, a1, a2, a3);
-}
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3,
-          typename A1, typename A2, typename A3>
-R call(const Process<T>* process,
-       R (T::*method)(P1, P2, P3),
-       A1 a1, A2 a2, A3 a3)
-{
-  return call (process->self(), method, a1, a2, a3);
-}
-
-
-////////////////////////////////////
-// Returning R via R with 4 args. //
-////////////////////////////////////
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-R call(const PID<T>& pid,
-       R (T::*method)(P1, P2, P3, P4),
-       A1 a1, A2 a2, A3 a3, A4 a4)
-{
-  return dispatch(pid, method, a1, a2, a3, a4).get();
-}
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-R call(const Process<T>& process,
-       R (T::*method)(P1, P2, P3, P4),
-       A1 a1, A2 a2, A3 a3, A4 a4)
-{
-  return call(process.self(), method, a1, a2, a3, a4);
-}
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4,
-          typename A1, typename A2, typename A3, typename A4>
-R call(const Process<T>* process,
-       R (T::*method)(P1, P2, P3, P4),
-       A1 a1, A2 a2, A3 a3, A4 a4)
-{
-  return call(process->self(), method, a1, a2, a3, a4);
-}
-
-
-////////////////////////////////////
-// Returning R via R with 5 args. //
-////////////////////////////////////
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-R call(const PID<T>& pid,
-       R (T::*method)(P1, P2, P3, P4, P5),
-       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
-{
-  return dispatch(pid, method, a1, a2, a3, a4, a5).get();
-}
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-R call(const Process<T>& process,
-       R (T::*method)(P1, P2, P3, P4, P5),
-       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
-{
-  return call(process.self(), method, a1, a2, a3, a4, a5);
-}
-
-template <typename R, typename T,
-          typename P1, typename P2, typename P3, typename P4, typename P5,
-          typename A1, typename A2, typename A3, typename A4, typename A5>
-R call(const Process<T>* process,
-       R (T::*method)(P1, P2, P3, P4, P5),
-       A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
-{
-  return call(process->self(), method, a1, a2, a3, a4, a5);
-}
+  REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
 
 } // namespace process {