1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style license that can be
5 // found in the LICENSE file.
6 
7 // A Tuple is a generic templatized container, similar in concept to std::pair.
8 // There are classes Tuple0 to Tuple6, cooresponding to the number of elements
9 // it contains.  The convenient MakeTuple() function takes 0 to 6 arguments,
10 // and will construct and return the appropriate Tuple object.  The functions
11 // DispatchToMethod and DispatchToFunction take a function pointer or instance
12 // and method pointer, and unpack a tuple into arguments to the call.
13 //
14 // Tuple elements are copied by value, and stored in the tuple.  See the unit
15 // tests for more details of how/when the values are copied.
16 //
17 // Example usage:
18 //   // These two methods of creating a Tuple are identical.
19 //   Tuple2<int, const char*> tuple_a(1, "wee");
20 //   Tuple2<int, const char*> tuple_b = MakeTuple(1, "wee");
21 //
22 //   void SomeFunc(int a, const char* b) { }
23 //   DispatchToFunction(&SomeFunc, tuple_a);  // SomeFunc(1, "wee")
24 //   DispatchToFunction(
25 //       &SomeFunc, MakeTuple(10, "foo"));    // SomeFunc(10, "foo")
26 //
27 //   struct { void SomeMeth(int a, int b, int c) { } } foo;
28 //   DispatchToMethod(&foo, &Foo::SomeMeth, MakeTuple(1, 2, 3));
29 //   // foo->SomeMeth(1, 2, 3);
30 
31 #ifndef BASE_TUPLE_H__
32 #define BASE_TUPLE_H__
33 
34 // Traits ----------------------------------------------------------------------
35 //
36 // A simple traits class for tuple arguments.
37 //
38 // ValueType: the bare, nonref version of a type (same as the type for nonrefs).
39 // RefType: the ref version of a type (same as the type for refs).
40 // ParamType: what type to pass to functions (refs should not be constified).
41 
42 template <class P>
43 struct TupleTraits {
44   typedef P ValueType;
45   typedef P& RefType;
46   typedef const P& ParamType;
47 };
48 
49 template <class P>
50 struct TupleTraits<P&> {
51   typedef P ValueType;
52   typedef P& RefType;
53   typedef P& ParamType;
54 };
55 
56 // Tuple -----------------------------------------------------------------------
57 //
58 // This set of classes is useful for bundling 0 or more heterogeneous data types
59 // into a single variable.  The advantage of this is that it greatly simplifies
60 // function objects that need to take an arbitrary number of parameters; see
61 // RunnableMethod and IPC::MessageWithTuple.
62 //
63 // Tuple0 is supplied to act as a 'void' type.  It can be used, for example,
64 // when dispatching to a function that accepts no arguments (see the
65 // Dispatchers below).
66 // Tuple1<A> is rarely useful.  One such use is when A is non-const ref that you
67 // want filled by the dispatchee, and the tuple is merely a container for that
68 // output (a "tier").  See MakeRefTuple and its usages.
69 
70 struct Tuple0 {
71   typedef Tuple0 ValueTuple;
72   typedef Tuple0 RefTuple;
73 };
74 
75 template <class A>
76 struct Tuple1 {
77  public:
78   typedef A TypeA;
79   typedef Tuple1<typename TupleTraits<A>::ValueType> ValueTuple;
80   typedef Tuple1<typename TupleTraits<A>::RefType> RefTuple;
81 
82   Tuple1() {}
83   explicit Tuple1(typename TupleTraits<A>::ParamType aA) : a(aA) {}
84 
85   A a;
86 };
87 
88 template <class A, class B>
89 struct Tuple2 {
90  public:
91   typedef A TypeA;
92   typedef B TypeB;
93   typedef Tuple2<typename TupleTraits<A>::ValueType,
94                  typename TupleTraits<B>::ValueType>
95       ValueTuple;
96   typedef Tuple2<typename TupleTraits<A>::RefType,
97                  typename TupleTraits<B>::RefType>
98       RefTuple;
99 
100   Tuple2() {}
101   Tuple2(typename TupleTraits<A>::ParamType aA,
102          typename TupleTraits<B>::ParamType aB)
103       : a(aA), b(aB) {}
104 
105   A a;
106   B b;
107 };
108 
109 template <class A, class B, class C>
110 struct Tuple3 {
111  public:
112   typedef A TypeA;
113   typedef B TypeB;
114   typedef C TypeC;
115   typedef Tuple3<typename TupleTraits<A>::ValueType,
116                  typename TupleTraits<B>::ValueType,
117                  typename TupleTraits<C>::ValueType>
118       ValueTuple;
119   typedef Tuple3<typename TupleTraits<A>::RefType,
120                  typename TupleTraits<B>::RefType,
121                  typename TupleTraits<C>::RefType>
122       RefTuple;
123 
124   Tuple3() {}
125   Tuple3(typename TupleTraits<A>::ParamType aA,
126          typename TupleTraits<B>::ParamType aB,
127          typename TupleTraits<C>::ParamType aC)
128       : a(aA), b(aB), c(aC) {}
129 
130   A a;
131   B b;
132   C c;
133 };
134 
135 template <class A, class B, class C, class D>
136 struct Tuple4 {
137  public:
138   typedef A TypeA;
139   typedef B TypeB;
140   typedef C TypeC;
141   typedef D TypeD;
142   typedef Tuple4<
143       typename TupleTraits<A>::ValueType, typename TupleTraits<B>::ValueType,
144       typename TupleTraits<C>::ValueType, typename TupleTraits<D>::ValueType>
145       ValueTuple;
146   typedef Tuple4<
147       typename TupleTraits<A>::RefType, typename TupleTraits<B>::RefType,
148       typename TupleTraits<C>::RefType, typename TupleTraits<D>::RefType>
149       RefTuple;
150 
151   Tuple4() {}
152   Tuple4(typename TupleTraits<A>::ParamType aA,
153          typename TupleTraits<B>::ParamType aB,
154          typename TupleTraits<C>::ParamType aC,
155          typename TupleTraits<D>::ParamType aD)
156       : a(aA), b(aB), c(aC), d(aD) {}
157 
158   A a;
159   B b;
160   C c;
161   D d;
162 };
163 
164 template <class A, class B, class C, class D, class E>
165 struct Tuple5 {
166  public:
167   typedef A TypeA;
168   typedef B TypeB;
169   typedef C TypeC;
170   typedef D TypeD;
171   typedef E TypeE;
172   typedef Tuple5<
173       typename TupleTraits<A>::ValueType, typename TupleTraits<B>::ValueType,
174       typename TupleTraits<C>::ValueType, typename TupleTraits<D>::ValueType,
175       typename TupleTraits<E>::ValueType>
176       ValueTuple;
177   typedef Tuple5<
178       typename TupleTraits<A>::RefType, typename TupleTraits<B>::RefType,
179       typename TupleTraits<C>::RefType, typename TupleTraits<D>::RefType,
180       typename TupleTraits<E>::RefType>
181       RefTuple;
182 
183   Tuple5() {}
184   Tuple5(typename TupleTraits<A>::ParamType aA,
185          typename TupleTraits<B>::ParamType aB,
186          typename TupleTraits<C>::ParamType aC,
187          typename TupleTraits<D>::ParamType aD,
188          typename TupleTraits<E>::ParamType aE)
189       : a(aA), b(aB), c(aC), d(aD), e(aE) {}
190 
191   A a;
192   B b;
193   C c;
194   D d;
195   E e;
196 };
197 
198 template <class A, class B, class C, class D, class E, class F>
199 struct Tuple6 {
200  public:
201   typedef A TypeA;
202   typedef B TypeB;
203   typedef C TypeC;
204   typedef D TypeD;
205   typedef E TypeE;
206   typedef F TypeF;
207   typedef Tuple6<
208       typename TupleTraits<A>::ValueType, typename TupleTraits<B>::ValueType,
209       typename TupleTraits<C>::ValueType, typename TupleTraits<D>::ValueType,
210       typename TupleTraits<E>::ValueType, typename TupleTraits<F>::ValueType>
211       ValueTuple;
212   typedef Tuple6<
213       typename TupleTraits<A>::RefType, typename TupleTraits<B>::RefType,
214       typename TupleTraits<C>::RefType, typename TupleTraits<D>::RefType,
215       typename TupleTraits<E>::RefType, typename TupleTraits<F>::RefType>
216       RefTuple;
217 
218   Tuple6() {}
219   Tuple6(typename TupleTraits<A>::ParamType aA,
220          typename TupleTraits<B>::ParamType aB,
221          typename TupleTraits<C>::ParamType aC,
222          typename TupleTraits<D>::ParamType aD,
223          typename TupleTraits<E>::ParamType aE,
224          typename TupleTraits<F>::ParamType aF)
225       : a(aA), b(aB), c(aC), d(aD), e(aE), f(aF) {}
226 
227   A a;
228   B b;
229   C c;
230   D d;
231   E e;
232   F f;
233 };
234 
235 template <class A, class B, class C, class D, class E, class F, class G>
236 struct Tuple7 {
237  public:
238   typedef A TypeA;
239   typedef B TypeB;
240   typedef C TypeC;
241   typedef D TypeD;
242   typedef E TypeE;
243   typedef F TypeF;
244   typedef G TypeG;
245   typedef Tuple7<
246       typename TupleTraits<A>::ValueType, typename TupleTraits<B>::ValueType,
247       typename TupleTraits<C>::ValueType, typename TupleTraits<D>::ValueType,
248       typename TupleTraits<E>::ValueType, typename TupleTraits<F>::ValueType,
249       typename TupleTraits<G>::ValueType>
250       ValueTuple;
251   typedef Tuple7<
252       typename TupleTraits<A>::RefType, typename TupleTraits<B>::RefType,
253       typename TupleTraits<C>::RefType, typename TupleTraits<D>::RefType,
254       typename TupleTraits<E>::RefType, typename TupleTraits<F>::RefType,
255       typename TupleTraits<G>::RefType>
256       RefTuple;
257 
258   Tuple7() {}
259   Tuple7(typename TupleTraits<A>::ParamType aA,
260          typename TupleTraits<B>::ParamType aB,
261          typename TupleTraits<C>::ParamType aC,
262          typename TupleTraits<D>::ParamType aD,
263          typename TupleTraits<E>::ParamType aE,
264          typename TupleTraits<F>::ParamType aF,
265          typename TupleTraits<G>::ParamType aG)
266       : a(aA), b(aB), c(aC), d(aD), e(aE), f(aF), g(aG) {}
267 
268   A a;
269   B b;
270   C c;
271   D d;
272   E e;
273   F f;
274   G g;
275 };
276 
277 // Tuple creators -------------------------------------------------------------
278 //
279 // Helper functions for constructing tuples while inferring the template
280 // argument types.
281 
282 namespace base {
283 
284 inline Tuple0 MakeTuple() { return Tuple0(); }
285 
286 template <class A>
287 inline Tuple1<A> MakeTuple(const A& a) {
288   return Tuple1<A>(a);
289 }
290 
291 template <class A, class B>
292 inline Tuple2<A, B> MakeTuple(const A& a, const B& b) {
293   return Tuple2<A, B>(a, b);
294 }
295 
296 template <class A, class B, class C>
297 inline Tuple3<A, B, C> MakeTuple(const A& a, const B& b, const C& c) {
298   return Tuple3<A, B, C>(a, b, c);
299 }
300 
301 template <class A, class B, class C, class D>
302 inline Tuple4<A, B, C, D> MakeTuple(const A& a, const B& b, const C& c,
303                                     const D& d) {
304   return Tuple4<A, B, C, D>(a, b, c, d);
305 }
306 
307 template <class A, class B, class C, class D, class E>
308 inline Tuple5<A, B, C, D, E> MakeTuple(const A& a, const B& b, const C& c,
309                                        const D& d, const E& e) {
310   return Tuple5<A, B, C, D, E>(a, b, c, d, e);
311 }
312 
313 template <class A, class B, class C, class D, class E, class F>
314 inline Tuple6<A, B, C, D, E, F> MakeTuple(const A& a, const B& b, const C& c,
315                                           const D& d, const E& e, const F& f) {
316   return Tuple6<A, B, C, D, E, F>(a, b, c, d, e, f);
317 }
318 
319 template <class A, class B, class C, class D, class E, class F, class G>
320 inline Tuple7<A, B, C, D, E, F, G> MakeTuple(const A& a, const B& b, const C& c,
321                                              const D& d, const E& e, const F& f,
322                                              const G& g) {
323   return Tuple7<A, B, C, D, E, F, G>(a, b, c, d, e, f, g);
324 }
325 
326 }  // end namespace base
327 
328 // The following set of helpers make what Boost refers to as "Tiers" - a tuple
329 // of references.
330 
331 template <class A>
332 inline Tuple1<A&> MakeRefTuple(A& a) {
333   return Tuple1<A&>(a);
334 }
335 
336 template <class A, class B>
337 inline Tuple2<A&, B&> MakeRefTuple(A& a, B& b) {
338   return Tuple2<A&, B&>(a, b);
339 }
340 
341 template <class A, class B, class C>
342 inline Tuple3<A&, B&, C&> MakeRefTuple(A& a, B& b, C& c) {
343   return Tuple3<A&, B&, C&>(a, b, c);
344 }
345 
346 template <class A, class B, class C, class D>
347 inline Tuple4<A&, B&, C&, D&> MakeRefTuple(A& a, B& b, C& c, D& d) {
348   return Tuple4<A&, B&, C&, D&>(a, b, c, d);
349 }
350 
351 template <class A, class B, class C, class D, class E>
352 inline Tuple5<A&, B&, C&, D&, E&> MakeRefTuple(A& a, B& b, C& c, D& d, E& e) {
353   return Tuple5<A&, B&, C&, D&, E&>(a, b, c, d, e);
354 }
355 
356 template <class A, class B, class C, class D, class E, class F>
357 inline Tuple6<A&, B&, C&, D&, E&, F&> MakeRefTuple(A& a, B& b, C& c, D& d, E& e,
358                                                    F& f) {
359   return Tuple6<A&, B&, C&, D&, E&, F&>(a, b, c, d, e, f);
360 }
361 
362 template <class A, class B, class C, class D, class E, class F, class G>
363 inline Tuple7<A&, B&, C&, D&, E&, F&, G&> MakeRefTuple(A& a, B& b, C& c, D& d,
364                                                        E& e, F& f, G& g) {
365   return Tuple7<A&, B&, C&, D&, E&, F&, G&>(a, b, c, d, e, f, g);
366 }
367 
368 // Dispatchers ----------------------------------------------------------------
369 //
370 // Helper functions that call the given method on an object, with the unpacked
371 // tuple arguments.  Notice that they all have the same number of arguments,
372 // so you need only write:
373 //   DispatchToMethod(object, &Object::method, args);
374 // This is very useful for templated dispatchers, since they don't need to know
375 // what type |args| is.
376 
377 // Non-Static Dispatchers with no out params.
378 
379 template <class ObjT, class Method>
380 inline void DispatchToMethod(ObjT* obj, Method method, const Tuple0& arg) {
381   (obj->*method)();
382 }
383 
384 template <class ObjT, class Method, class A>
385 inline void DispatchToMethod(ObjT* obj, Method method, const A& arg) {
386   (obj->*method)(arg);
387 }
388 
389 template <class ObjT, class Method, class A>
390 inline void DispatchToMethod(ObjT* obj, Method method, const Tuple1<A>& arg) {
391   (obj->*method)(arg.a);
392 }
393 
394 template <class ObjT, class Method, class A, class B>
395 inline void DispatchToMethod(ObjT* obj, Method method,
396                              const Tuple2<A, B>& arg) {
397   (obj->*method)(arg.a, arg.b);
398 }
399 
400 template <class ObjT, class Method, class A, class B, class C>
401 inline void DispatchToMethod(ObjT* obj, Method method,
402                              const Tuple3<A, B, C>& arg) {
403   (obj->*method)(arg.a, arg.b, arg.c);
404 }
405 
406 template <class ObjT, class Method, class A, class B, class C, class D>
407 inline void DispatchToMethod(ObjT* obj, Method method,
408                              const Tuple4<A, B, C, D>& arg) {
409   (obj->*method)(arg.a, arg.b, arg.c, arg.d);
410 }
411 
412 template <class ObjT, class Method, class A, class B, class C, class D, class E>
413 inline void DispatchToMethod(ObjT* obj, Method method,
414                              const Tuple5<A, B, C, D, E>& arg) {
415   (obj->*method)(arg.a, arg.b, arg.c, arg.d, arg.e);
416 }
417 
418 template <class ObjT, class Method, class A, class B, class C, class D, class E,
419           class F>
420 inline void DispatchToMethod(ObjT* obj, Method method,
421                              const Tuple6<A, B, C, D, E, F>& arg) {
422   (obj->*method)(arg.a, arg.b, arg.c, arg.d, arg.e, arg.f);
423 }
424 
425 template <class ObjT, class Method, class A, class B, class C, class D, class E,
426           class F, class G>
427 inline void DispatchToMethod(ObjT* obj, Method method,
428                              const Tuple7<A, B, C, D, E, F, G>& arg) {
429   (obj->*method)(arg.a, arg.b, arg.c, arg.d, arg.e, arg.f, arg.g);
430 }
431 
432 // Static Dispatchers with no out params.
433 
434 template <class Function>
435 inline void DispatchToFunction(Function function, const Tuple0& arg) {
436   (*function)();
437 }
438 
439 template <class Function, class A>
440 inline void DispatchToFunction(Function function, const A& arg) {
441   (*function)(arg);
442 }
443 
444 template <class Function, class A>
445 inline void DispatchToFunction(Function function, const Tuple1<A>& arg) {
446   (*function)(arg.a);
447 }
448 
449 template <class Function, class A, class B>
450 inline void DispatchToFunction(Function function, const Tuple2<A, B>& arg) {
451   (*function)(arg.a, arg.b);
452 }
453 
454 template <class Function, class A, class B, class C>
455 inline void DispatchToFunction(Function function, const Tuple3<A, B, C>& arg) {
456   (*function)(arg.a, arg.b, arg.c);
457 }
458 
459 template <class Function, class A, class B, class C, class D>
460 inline void DispatchToFunction(Function function,
461                                const Tuple4<A, B, C, D>& arg) {
462   (*function)(arg.a, arg.b, arg.c, arg.d);
463 }
464 
465 template <class Function, class A, class B, class C, class D, class E>
466 inline void DispatchToFunction(Function function,
467                                const Tuple5<A, B, C, D, E>& arg) {
468   (*function)(arg.a, arg.b, arg.c, arg.d, arg.e);
469 }
470 
471 template <class Function, class A, class B, class C, class D, class E, class F>
472 inline void DispatchToFunction(Function function,
473                                const Tuple6<A, B, C, D, E, F>& arg) {
474   (*function)(arg.a, arg.b, arg.c, arg.d, arg.e, arg.f);
475 }
476 
477 // Dispatchers with 0 out param (as a Tuple0).
478 
479 template <class ObjT, class Method>
480 inline void DispatchToMethod(ObjT* obj, Method method, const Tuple0& arg,
481                              Tuple0*) {
482   (obj->*method)();
483 }
484 
485 template <class ObjT, class Method, class A>
486 inline void DispatchToMethod(ObjT* obj, Method method, const A& arg, Tuple0*) {
487   (obj->*method)(arg);
488 }
489 
490 template <class ObjT, class Method, class A>
491 inline void DispatchToMethod(ObjT* obj, Method method, const Tuple1<A>& arg,
492                              Tuple0*) {
493   (obj->*method)(arg.a);
494 }
495 
496 template <class ObjT, class Method, class A, class B>
497 inline void DispatchToMethod(ObjT* obj, Method method, const Tuple2<A, B>& arg,
498                              Tuple0*) {
499   (obj->*method)(arg.a, arg.b);
500 }
501 
502 template <class ObjT, class Method, class A, class B, class C>
503 inline void DispatchToMethod(ObjT* obj, Method method,
504                              const Tuple3<A, B, C>& arg, Tuple0*) {
505   (obj->*method)(arg.a, arg.b, arg.c);
506 }
507 
508 template <class ObjT, class Method, class A, class B, class C, class D>
509 inline void DispatchToMethod(ObjT* obj, Method method,
510                              const Tuple4<A, B, C, D>& arg, Tuple0*) {
511   (obj->*method)(arg.a, arg.b, arg.c, arg.d);
512 }
513 
514 template <class ObjT, class Method, class A, class B, class C, class D, class E>
515 inline void DispatchToMethod(ObjT* obj, Method method,
516                              const Tuple5<A, B, C, D, E>& arg, Tuple0*) {
517   (obj->*method)(arg.a, arg.b, arg.c, arg.d, arg.e);
518 }
519 
520 template <class ObjT, class Method, class A, class B, class C, class D, class E,
521           class F>
522 inline void DispatchToMethod(ObjT* obj, Method method,
523                              const Tuple6<A, B, C, D, E, F>& arg, Tuple0*) {
524   (obj->*method)(arg.a, arg.b, arg.c, arg.d, arg.e, arg.f);
525 }
526 
527 // Dispatchers with 1 out param.
528 
529 template <class ObjT, class Method, class OutA>
530 inline void DispatchToMethod(ObjT* obj, Method method, const Tuple0& in,
531                              Tuple1<OutA>* out) {
532   (obj->*method)(&out->a);
533 }
534 
535 template <class ObjT, class Method, class InA, class OutA>
536 inline void DispatchToMethod(ObjT* obj, Method method, const InA& in,
537                              Tuple1<OutA>* out) {
538   (obj->*method)(in, &out->a);
539 }
540 
541 template <class ObjT, class Method, class InA, class OutA>
542 inline void DispatchToMethod(ObjT* obj, Method method, const Tuple1<InA>& in,
543                              Tuple1<OutA>* out) {
544   (obj->*method)(in.a, &out->a);
545 }
546 
547 template <class ObjT, class Method, class InA, class InB, class OutA>
548 inline void DispatchToMethod(ObjT* obj, Method method,
549                              const Tuple2<InA, InB>& in, Tuple1<OutA>* out) {
550   (obj->*method)(in.a, in.b, &out->a);
551 }
552 
553 template <class ObjT, class Method, class InA, class InB, class InC, class OutA>
554 inline void DispatchToMethod(ObjT* obj, Method method,
555                              const Tuple3<InA, InB, InC>& in,
556                              Tuple1<OutA>* out) {
557   (obj->*method)(in.a, in.b, in.c, &out->a);
558 }
559 
560 template <class ObjT, class Method, class InA, class InB, class InC, class InD,
561           class OutA>
562 inline void DispatchToMethod(ObjT* obj, Method method,
563                              const Tuple4<InA, InB, InC, InD>& in,
564                              Tuple1<OutA>* out) {
565   (obj->*method)(in.a, in.b, in.c, in.d, &out->a);
566 }
567 
568 template <class ObjT, class Method, class InA, class InB, class InC, class InD,
569           class InE, class OutA>
570 inline void DispatchToMethod(ObjT* obj, Method method,
571                              const Tuple5<InA, InB, InC, InD, InE>& in,
572                              Tuple1<OutA>* out) {
573   (obj->*method)(in.a, in.b, in.c, in.d, in.e, &out->a);
574 }
575 
576 template <class ObjT, class Method, class InA, class InB, class InC, class InD,
577           class InE, class InF, class OutA>
578 inline void DispatchToMethod(ObjT* obj, Method method,
579                              const Tuple6<InA, InB, InC, InD, InE, InF>& in,
580                              Tuple1<OutA>* out) {
581   (obj->*method)(in.a, in.b, in.c, in.d, in.e, in.f, &out->a);
582 }
583 
584 // Dispatchers with 2 out params.
585 
586 template <class ObjT, class Method, class OutA, class OutB>
587 inline void DispatchToMethod(ObjT* obj, Method method, const Tuple0& in,
588                              Tuple2<OutA, OutB>* out) {
589   (obj->*method)(&out->a, &out->b);
590 }
591 
592 template <class ObjT, class Method, class InA, class OutA, class OutB>
593 inline void DispatchToMethod(ObjT* obj, Method method, const InA& in,
594                              Tuple2<OutA, OutB>* out) {
595   (obj->*method)(in, &out->a, &out->b);
596 }
597 
598 template <class ObjT, class Method, class InA, class OutA, class OutB>
599 inline void DispatchToMethod(ObjT* obj, Method method, const Tuple1<InA>& in,
600                              Tuple2<OutA, OutB>* out) {
601   (obj->*method)(in.a, &out->a, &out->b);
602 }
603 
604 template <class ObjT, class Method, class InA, class InB, class OutA,
605           class OutB>
606 inline void DispatchToMethod(ObjT* obj, Method method,
607                              const Tuple2<InA, InB>& in,
608                              Tuple2<OutA, OutB>* out) {
609   (obj->*method)(in.a, in.b, &out->a, &out->b);
610 }
611 
612 template <class ObjT, class Method, class InA, class InB, class InC, class OutA,
613           class OutB>
614 inline void DispatchToMethod(ObjT* obj, Method method,
615                              const Tuple3<InA, InB, InC>& in,
616                              Tuple2<OutA, OutB>* out) {
617   (obj->*method)(in.a, in.b, in.c, &out->a, &out->b);
618 }
619 
620 template <class ObjT, class Method, class InA, class InB, class InC, class InD,
621           class OutA, class OutB>
622 inline void DispatchToMethod(ObjT* obj, Method method,
623                              const Tuple4<InA, InB, InC, InD>& in,
624                              Tuple2<OutA, OutB>* out) {
625   (obj->*method)(in.a, in.b, in.c, in.d, &out->a, &out->b);
626 }
627 
628 template <class ObjT, class Method, class InA, class InB, class InC, class InD,
629           class InE, class OutA, class OutB>
630 inline void DispatchToMethod(ObjT* obj, Method method,
631                              const Tuple5<InA, InB, InC, InD, InE>& in,
632                              Tuple2<OutA, OutB>* out) {
633   (obj->*method)(in.a, in.b, in.c, in.d, in.e, &out->a, &out->b);
634 }
635 
636 template <class ObjT, class Method, class InA, class InB, class InC, class InD,
637           class InE, class InF, class OutA, class OutB>
638 inline void DispatchToMethod(ObjT* obj, Method method,
639                              const Tuple6<InA, InB, InC, InD, InE, InF>& in,
640                              Tuple2<OutA, OutB>* out) {
641   (obj->*method)(in.a, in.b, in.c, in.d, in.e, in.f, &out->a, &out->b);
642 }
643 
644 // Dispatchers with 3 out params.
645 
646 template <class ObjT, class Method, class OutA, class OutB, class OutC>
647 inline void DispatchToMethod(ObjT* obj, Method method, const Tuple0& in,
648                              Tuple3<OutA, OutB, OutC>* out) {
649   (obj->*method)(&out->a, &out->b, &out->c);
650 }
651 
652 template <class ObjT, class Method, class InA, class OutA, class OutB,
653           class OutC>
654 inline void DispatchToMethod(ObjT* obj, Method method, const InA& in,
655                              Tuple3<OutA, OutB, OutC>* out) {
656   (obj->*method)(in, &out->a, &out->b, &out->c);
657 }
658 
659 template <class ObjT, class Method, class InA, class OutA, class OutB,
660           class OutC>
661 inline void DispatchToMethod(ObjT* obj, Method method, const Tuple1<InA>& in,
662                              Tuple3<OutA, OutB, OutC>* out) {
663   (obj->*method)(in.a, &out->a, &out->b, &out->c);
664 }
665 
666 template <class ObjT, class Method, class InA, class InB, class OutA,
667           class OutB, class OutC>
668 inline void DispatchToMethod(ObjT* obj, Method method,
669                              const Tuple2<InA, InB>& in,
670                              Tuple3<OutA, OutB, OutC>* out) {
671   (obj->*method)(in.a, in.b, &out->a, &out->b, &out->c);
672 }
673 
674 template <class ObjT, class Method, class InA, class InB, class InC, class OutA,
675           class OutB, class OutC>
676 inline void DispatchToMethod(ObjT* obj, Method method,
677                              const Tuple3<InA, InB, InC>& in,
678                              Tuple3<OutA, OutB, OutC>* out) {
679   (obj->*method)(in.a, in.b, in.c, &out->a, &out->b, &out->c);
680 }
681 
682 template <class ObjT, class Method, class InA, class InB, class InC, class InD,
683           class OutA, class OutB, class OutC>
684 inline void DispatchToMethod(ObjT* obj, Method method,
685                              const Tuple4<InA, InB, InC, InD>& in,
686                              Tuple3<OutA, OutB, OutC>* out) {
687   (obj->*method)(in.a, in.b, in.c, in.d, &out->a, &out->b, &out->c);
688 }
689 
690 template <class ObjT, class Method, class InA, class InB, class InC, class InD,
691           class InE, class OutA, class OutB, class OutC>
692 inline void DispatchToMethod(ObjT* obj, Method method,
693                              const Tuple5<InA, InB, InC, InD, InE>& in,
694                              Tuple3<OutA, OutB, OutC>* out) {
695   (obj->*method)(in.a, in.b, in.c, in.d, in.e, &out->a, &out->b, &out->c);
696 }
697 
698 template <class ObjT, class Method, class InA, class InB, class InC, class InD,
699           class InE, class InF, class OutA, class OutB, class OutC>
700 inline void DispatchToMethod(ObjT* obj, Method method,
701                              const Tuple6<InA, InB, InC, InD, InE, InF>& in,
702                              Tuple3<OutA, OutB, OutC>* out) {
703   (obj->*method)(in.a, in.b, in.c, in.d, in.e, in.f, &out->a, &out->b, &out->c);
704 }
705 
706 // Dispatchers with 4 out params.
707 
708 template <class ObjT, class Method, class OutA, class OutB, class OutC,
709           class OutD>
710 inline void DispatchToMethod(ObjT* obj, Method method, const Tuple0& in,
711                              Tuple4<OutA, OutB, OutC, OutD>* out) {
712   (obj->*method)(&out->a, &out->b, &out->c, &out->d);
713 }
714 
715 template <class ObjT, class Method, class InA, class OutA, class OutB,
716           class OutC, class OutD>
717 inline void DispatchToMethod(ObjT* obj, Method method, const InA& in,
718                              Tuple4<OutA, OutB, OutC, OutD>* out) {
719   (obj->*method)(in, &out->a, &out->b, &out->c, &out->d);
720 }
721 
722 template <class ObjT, class Method, class InA, class OutA, class OutB,
723           class OutC, class OutD>
724 inline void DispatchToMethod(ObjT* obj, Method method, const Tuple1<InA>& in,
725                              Tuple4<OutA, OutB, OutC, OutD>* out) {
726   (obj->*method)(in.a, &out->a, &out->b, &out->c, &out->d);
727 }
728 
729 template <class ObjT, class Method, class InA, class InB, class OutA,
730           class OutB, class OutC, class OutD>
731 inline void DispatchToMethod(ObjT* obj, Method method,
732                              const Tuple2<InA, InB>& in,
733                              Tuple4<OutA, OutB, OutC, OutD>* out) {
734   (obj->*method)(in.a, in.b, &out->a, &out->b, &out->c, &out->d);
735 }
736 
737 template <class ObjT, class Method, class InA, class InB, class InC, class OutA,
738           class OutB, class OutC, class OutD>
739 inline void DispatchToMethod(ObjT* obj, Method method,
740                              const Tuple3<InA, InB, InC>& in,
741                              Tuple4<OutA, OutB, OutC, OutD>* out) {
742   (obj->*method)(in.a, in.b, in.c, &out->a, &out->b, &out->c, &out->d);
743 }
744 
745 template <class ObjT, class Method, class InA, class InB, class InC, class InD,
746           class OutA, class OutB, class OutC, class OutD>
747 inline void DispatchToMethod(ObjT* obj, Method method,
748                              const Tuple4<InA, InB, InC, InD>& in,
749                              Tuple4<OutA, OutB, OutC, OutD>* out) {
750   (obj->*method)(in.a, in.b, in.c, in.d, &out->a, &out->b, &out->c, &out->d);
751 }
752 
753 template <class ObjT, class Method, class InA, class InB, class InC, class InD,
754           class InE, class OutA, class OutB, class OutC, class OutD>
755 inline void DispatchToMethod(ObjT* obj, Method method,
756                              const Tuple5<InA, InB, InC, InD, InE>& in,
757                              Tuple4<OutA, OutB, OutC, OutD>* out) {
758   (obj->*method)(in.a, in.b, in.c, in.d, in.e, &out->a, &out->b, &out->c,
759                  &out->d);
760 }
761 
762 template <class ObjT, class Method, class InA, class InB, class InC, class InD,
763           class InE, class InF, class OutA, class OutB, class OutC, class OutD>
764 inline void DispatchToMethod(ObjT* obj, Method method,
765                              const Tuple6<InA, InB, InC, InD, InE, InF>& in,
766                              Tuple4<OutA, OutB, OutC, OutD>* out) {
767   (obj->*method)(in.a, in.b, in.c, in.d, in.e, in.f, &out->a, &out->b, &out->c,
768                  &out->d);
769 }
770 
771 // Dispatchers with 5 out params.
772 
773 template <class ObjT, class Method, class OutA, class OutB, class OutC,
774           class OutD, class OutE>
775 inline void DispatchToMethod(ObjT* obj, Method method, const Tuple0& in,
776                              Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
777   (obj->*method)(&out->a, &out->b, &out->c, &out->d, &out->e);
778 }
779 
780 template <class ObjT, class Method, class InA, class OutA, class OutB,
781           class OutC, class OutD, class OutE>
782 inline void DispatchToMethod(ObjT* obj, Method method, const InA& in,
783                              Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
784   (obj->*method)(in, &out->a, &out->b, &out->c, &out->d, &out->e);
785 }
786 
787 template <class ObjT, class Method, class InA, class OutA, class OutB,
788           class OutC, class OutD, class OutE>
789 inline void DispatchToMethod(ObjT* obj, Method method, const Tuple1<InA>& in,
790                              Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
791   (obj->*method)(in.a, &out->a, &out->b, &out->c, &out->d, &out->e);
792 }
793 
794 template <class ObjT, class Method, class InA, class InB, class OutA,
795           class OutB, class OutC, class OutD, class OutE>
796 inline void DispatchToMethod(ObjT* obj, Method method,
797                              const Tuple2<InA, InB>& in,
798                              Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
799   (obj->*method)(in.a, in.b, &out->a, &out->b, &out->c, &out->d, &out->e);
800 }
801 
802 template <class ObjT, class Method, class InA, class InB, class InC, class OutA,
803           class OutB, class OutC, class OutD, class OutE>
804 inline void DispatchToMethod(ObjT* obj, Method method,
805                              const Tuple3<InA, InB, InC>& in,
806                              Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
807   (obj->*method)(in.a, in.b, in.c, &out->a, &out->b, &out->c, &out->d, &out->e);
808 }
809 
810 template <class ObjT, class Method, class InA, class InB, class InC, class InD,
811           class OutA, class OutB, class OutC, class OutD, class OutE>
812 inline void DispatchToMethod(ObjT* obj, Method method,
813                              const Tuple4<InA, InB, InC, InD>& in,
814                              Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
815   (obj->*method)(in.a, in.b, in.c, in.d, &out->a, &out->b, &out->c, &out->d,
816                  &out->e);
817 }
818 
819 template <class ObjT, class Method, class InA, class InB, class InC, class InD,
820           class InE, class OutA, class OutB, class OutC, class OutD, class OutE>
821 inline void DispatchToMethod(ObjT* obj, Method method,
822                              const Tuple5<InA, InB, InC, InD, InE>& in,
823                              Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
824   (obj->*method)(in.a, in.b, in.c, in.d, in.e, &out->a, &out->b, &out->c,
825                  &out->d, &out->e);
826 }
827 
828 template <class ObjT, class Method, class InA, class InB, class InC, class InD,
829           class InE, class InF, class OutA, class OutB, class OutC, class OutD,
830           class OutE>
831 inline void DispatchToMethod(ObjT* obj, Method method,
832                              const Tuple6<InA, InB, InC, InD, InE, InF>& in,
833                              Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
834   (obj->*method)(in.a, in.b, in.c, in.d, in.e, in.f, &out->a, &out->b, &out->c,
835                  &out->d, &out->e);
836 }
837 
838 #endif  // BASE_TUPLE_H__
839