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