• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 #include "base/bind_helpers.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 template <class P>
57 struct TupleTypes { };
58 
59 // Tuple -----------------------------------------------------------------------
60 //
61 // This set of classes is useful for bundling 0 or more heterogeneous data types
62 // into a single variable.  The advantage of this is that it greatly simplifies
63 // function objects that need to take an arbitrary number of parameters; see
64 // RunnableMethod and IPC::MessageWithTuple.
65 //
66 // Tuple0 is supplied to act as a 'void' type.  It can be used, for example,
67 // when dispatching to a function that accepts no arguments (see the
68 // Dispatchers below).
69 // Tuple1<A> is rarely useful.  One such use is when A is non-const ref that you
70 // want filled by the dispatchee, and the tuple is merely a container for that
71 // output (a "tier").  See MakeRefTuple and its usages.
72 
73 struct Tuple0 {
74   typedef Tuple0 ValueTuple;
75   typedef Tuple0 RefTuple;
76   typedef Tuple0 ParamTuple;
77 };
78 
79 template <class A>
80 struct Tuple1 {
81  public:
82   typedef A TypeA;
83 
84   Tuple1() {}
85   explicit Tuple1(typename TupleTraits<A>::ParamType a) : a(a) {}
86 
87   A a;
88 };
89 
90 template <class A, class B>
91 struct Tuple2 {
92  public:
93   typedef A TypeA;
94   typedef B TypeB;
95 
96   Tuple2() {}
97   Tuple2(typename TupleTraits<A>::ParamType a,
98          typename TupleTraits<B>::ParamType b)
99       : a(a), b(b) {
100   }
101 
102   A a;
103   B b;
104 };
105 
106 template <class A, class B, class C>
107 struct Tuple3 {
108  public:
109   typedef A TypeA;
110   typedef B TypeB;
111   typedef C TypeC;
112 
113   Tuple3() {}
114   Tuple3(typename TupleTraits<A>::ParamType a,
115          typename TupleTraits<B>::ParamType b,
116          typename TupleTraits<C>::ParamType c)
117       : a(a), b(b), c(c){
118   }
119 
120   A a;
121   B b;
122   C c;
123 };
124 
125 template <class A, class B, class C, class D>
126 struct Tuple4 {
127  public:
128   typedef A TypeA;
129   typedef B TypeB;
130   typedef C TypeC;
131   typedef D TypeD;
132 
133   Tuple4() {}
134   Tuple4(typename TupleTraits<A>::ParamType a,
135          typename TupleTraits<B>::ParamType b,
136          typename TupleTraits<C>::ParamType c,
137          typename TupleTraits<D>::ParamType d)
138       : a(a), b(b), c(c), d(d) {
139   }
140 
141   A a;
142   B b;
143   C c;
144   D d;
145 };
146 
147 template <class A, class B, class C, class D, class E>
148 struct Tuple5 {
149  public:
150   typedef A TypeA;
151   typedef B TypeB;
152   typedef C TypeC;
153   typedef D TypeD;
154   typedef E TypeE;
155 
156   Tuple5() {}
157   Tuple5(typename TupleTraits<A>::ParamType a,
158     typename TupleTraits<B>::ParamType b,
159     typename TupleTraits<C>::ParamType c,
160     typename TupleTraits<D>::ParamType d,
161     typename TupleTraits<E>::ParamType e)
162     : a(a), b(b), c(c), d(d), e(e) {
163   }
164 
165   A a;
166   B b;
167   C c;
168   D d;
169   E e;
170 };
171 
172 template <class A, class B, class C, class D, class E, class F>
173 struct Tuple6 {
174  public:
175   typedef A TypeA;
176   typedef B TypeB;
177   typedef C TypeC;
178   typedef D TypeD;
179   typedef E TypeE;
180   typedef F TypeF;
181 
182   Tuple6() {}
183   Tuple6(typename TupleTraits<A>::ParamType a,
184     typename TupleTraits<B>::ParamType b,
185     typename TupleTraits<C>::ParamType c,
186     typename TupleTraits<D>::ParamType d,
187     typename TupleTraits<E>::ParamType e,
188     typename TupleTraits<F>::ParamType f)
189     : a(a), b(b), c(c), d(d), e(e), f(f) {
190   }
191 
192   A a;
193   B b;
194   C c;
195   D d;
196   E e;
197   F f;
198 };
199 
200 template <class A, class B, class C, class D, class E, class F, class G>
201 struct Tuple7 {
202  public:
203   typedef A TypeA;
204   typedef B TypeB;
205   typedef C TypeC;
206   typedef D TypeD;
207   typedef E TypeE;
208   typedef F TypeF;
209   typedef G TypeG;
210 
211   Tuple7() {}
212   Tuple7(typename TupleTraits<A>::ParamType a,
213     typename TupleTraits<B>::ParamType b,
214     typename TupleTraits<C>::ParamType c,
215     typename TupleTraits<D>::ParamType d,
216     typename TupleTraits<E>::ParamType e,
217     typename TupleTraits<F>::ParamType f,
218     typename TupleTraits<G>::ParamType g)
219     : a(a), b(b), c(c), d(d), e(e), f(f), g(g) {
220   }
221 
222   A a;
223   B b;
224   C c;
225   D d;
226   E e;
227   F f;
228   G g;
229 };
230 
231 template <class A, class B, class C, class D, class E, class F, class G,
232           class H>
233 struct Tuple8 {
234  public:
235   typedef A TypeA;
236   typedef B TypeB;
237   typedef C TypeC;
238   typedef D TypeD;
239   typedef E TypeE;
240   typedef F TypeF;
241   typedef G TypeG;
242   typedef H TypeH;
243 
244   Tuple8() {}
245   Tuple8(typename TupleTraits<A>::ParamType a,
246     typename TupleTraits<B>::ParamType b,
247     typename TupleTraits<C>::ParamType c,
248     typename TupleTraits<D>::ParamType d,
249     typename TupleTraits<E>::ParamType e,
250     typename TupleTraits<F>::ParamType f,
251     typename TupleTraits<G>::ParamType g,
252     typename TupleTraits<H>::ParamType h)
253     : a(a), b(b), c(c), d(d), e(e), f(f), g(g), h(h) {
254   }
255 
256   A a;
257   B b;
258   C c;
259   D d;
260   E e;
261   F f;
262   G g;
263   H h;
264 };
265 
266 // Tuple types ----------------------------------------------------------------
267 //
268 // Allows for selection of ValueTuple/RefTuple/ParamTuple without needing the
269 // definitions of class types the tuple takes as parameters.
270 
271 template <>
272 struct TupleTypes< Tuple0 > {
273   typedef Tuple0 ValueTuple;
274   typedef Tuple0 RefTuple;
275   typedef Tuple0 ParamTuple;
276 };
277 
278 template <class A>
279 struct TupleTypes< Tuple1<A> > {
280   typedef Tuple1<typename TupleTraits<A>::ValueType> ValueTuple;
281   typedef Tuple1<typename TupleTraits<A>::RefType> RefTuple;
282   typedef Tuple1<typename TupleTraits<A>::ParamType> ParamTuple;
283 };
284 
285 template <class A, class B>
286 struct TupleTypes< Tuple2<A, B> > {
287   typedef Tuple2<typename TupleTraits<A>::ValueType,
288                  typename TupleTraits<B>::ValueType> ValueTuple;
289 typedef Tuple2<typename TupleTraits<A>::RefType,
290                typename TupleTraits<B>::RefType> RefTuple;
291   typedef Tuple2<typename TupleTraits<A>::ParamType,
292                  typename TupleTraits<B>::ParamType> ParamTuple;
293 };
294 
295 template <class A, class B, class C>
296 struct TupleTypes< Tuple3<A, B, C> > {
297   typedef Tuple3<typename TupleTraits<A>::ValueType,
298                  typename TupleTraits<B>::ValueType,
299                  typename TupleTraits<C>::ValueType> ValueTuple;
300 typedef Tuple3<typename TupleTraits<A>::RefType,
301                typename TupleTraits<B>::RefType,
302                typename TupleTraits<C>::RefType> RefTuple;
303   typedef Tuple3<typename TupleTraits<A>::ParamType,
304                  typename TupleTraits<B>::ParamType,
305                  typename TupleTraits<C>::ParamType> ParamTuple;
306 };
307 
308 template <class A, class B, class C, class D>
309 struct TupleTypes< Tuple4<A, B, C, D> > {
310   typedef Tuple4<typename TupleTraits<A>::ValueType,
311                  typename TupleTraits<B>::ValueType,
312                  typename TupleTraits<C>::ValueType,
313                  typename TupleTraits<D>::ValueType> ValueTuple;
314 typedef Tuple4<typename TupleTraits<A>::RefType,
315                typename TupleTraits<B>::RefType,
316                typename TupleTraits<C>::RefType,
317                typename TupleTraits<D>::RefType> RefTuple;
318   typedef Tuple4<typename TupleTraits<A>::ParamType,
319                  typename TupleTraits<B>::ParamType,
320                  typename TupleTraits<C>::ParamType,
321                  typename TupleTraits<D>::ParamType> ParamTuple;
322 };
323 
324 template <class A, class B, class C, class D, class E>
325 struct TupleTypes< Tuple5<A, B, C, D, E> > {
326   typedef Tuple5<typename TupleTraits<A>::ValueType,
327                  typename TupleTraits<B>::ValueType,
328                  typename TupleTraits<C>::ValueType,
329                  typename TupleTraits<D>::ValueType,
330                  typename TupleTraits<E>::ValueType> ValueTuple;
331 typedef Tuple5<typename TupleTraits<A>::RefType,
332                typename TupleTraits<B>::RefType,
333                typename TupleTraits<C>::RefType,
334                typename TupleTraits<D>::RefType,
335                typename TupleTraits<E>::RefType> RefTuple;
336   typedef Tuple5<typename TupleTraits<A>::ParamType,
337                  typename TupleTraits<B>::ParamType,
338                  typename TupleTraits<C>::ParamType,
339                  typename TupleTraits<D>::ParamType,
340                  typename TupleTraits<E>::ParamType> ParamTuple;
341 };
342 
343 template <class A, class B, class C, class D, class E, class F>
344 struct TupleTypes< Tuple6<A, B, C, D, E, F> > {
345   typedef Tuple6<typename TupleTraits<A>::ValueType,
346                  typename TupleTraits<B>::ValueType,
347                  typename TupleTraits<C>::ValueType,
348                  typename TupleTraits<D>::ValueType,
349                  typename TupleTraits<E>::ValueType,
350                  typename TupleTraits<F>::ValueType> ValueTuple;
351 typedef Tuple6<typename TupleTraits<A>::RefType,
352                typename TupleTraits<B>::RefType,
353                typename TupleTraits<C>::RefType,
354                typename TupleTraits<D>::RefType,
355                typename TupleTraits<E>::RefType,
356                typename TupleTraits<F>::RefType> RefTuple;
357   typedef Tuple6<typename TupleTraits<A>::ParamType,
358                  typename TupleTraits<B>::ParamType,
359                  typename TupleTraits<C>::ParamType,
360                  typename TupleTraits<D>::ParamType,
361                  typename TupleTraits<E>::ParamType,
362                  typename TupleTraits<F>::ParamType> ParamTuple;
363 };
364 
365 template <class A, class B, class C, class D, class E, class F, class G>
366 struct TupleTypes< Tuple7<A, B, C, D, E, F, G> > {
367   typedef Tuple7<typename TupleTraits<A>::ValueType,
368                  typename TupleTraits<B>::ValueType,
369                  typename TupleTraits<C>::ValueType,
370                  typename TupleTraits<D>::ValueType,
371                  typename TupleTraits<E>::ValueType,
372                  typename TupleTraits<F>::ValueType,
373                  typename TupleTraits<G>::ValueType> ValueTuple;
374 typedef Tuple7<typename TupleTraits<A>::RefType,
375                typename TupleTraits<B>::RefType,
376                typename TupleTraits<C>::RefType,
377                typename TupleTraits<D>::RefType,
378                typename TupleTraits<E>::RefType,
379                typename TupleTraits<F>::RefType,
380                typename TupleTraits<G>::RefType> RefTuple;
381   typedef Tuple7<typename TupleTraits<A>::ParamType,
382                  typename TupleTraits<B>::ParamType,
383                  typename TupleTraits<C>::ParamType,
384                  typename TupleTraits<D>::ParamType,
385                  typename TupleTraits<E>::ParamType,
386                  typename TupleTraits<F>::ParamType,
387                  typename TupleTraits<G>::ParamType> ParamTuple;
388 };
389 
390 template <class A, class B, class C, class D, class E, class F, class G,
391           class H>
392 struct TupleTypes< Tuple8<A, B, C, D, E, F, G, H> > {
393   typedef Tuple8<typename TupleTraits<A>::ValueType,
394                  typename TupleTraits<B>::ValueType,
395                  typename TupleTraits<C>::ValueType,
396                  typename TupleTraits<D>::ValueType,
397                  typename TupleTraits<E>::ValueType,
398                  typename TupleTraits<F>::ValueType,
399                  typename TupleTraits<G>::ValueType,
400                  typename TupleTraits<H>::ValueType> ValueTuple;
401 typedef Tuple8<typename TupleTraits<A>::RefType,
402                typename TupleTraits<B>::RefType,
403                typename TupleTraits<C>::RefType,
404                typename TupleTraits<D>::RefType,
405                typename TupleTraits<E>::RefType,
406                typename TupleTraits<F>::RefType,
407                typename TupleTraits<G>::RefType,
408                typename TupleTraits<H>::RefType> RefTuple;
409   typedef Tuple8<typename TupleTraits<A>::ParamType,
410                  typename TupleTraits<B>::ParamType,
411                  typename TupleTraits<C>::ParamType,
412                  typename TupleTraits<D>::ParamType,
413                  typename TupleTraits<E>::ParamType,
414                  typename TupleTraits<F>::ParamType,
415                  typename TupleTraits<G>::ParamType,
416                  typename TupleTraits<H>::ParamType> ParamTuple;
417 };
418 
419 // Tuple creators -------------------------------------------------------------
420 //
421 // Helper functions for constructing tuples while inferring the template
422 // argument types.
423 
424 inline Tuple0 MakeTuple() {
425   return Tuple0();
426 }
427 
428 template <class A>
429 inline Tuple1<A> MakeTuple(const A& a) {
430   return Tuple1<A>(a);
431 }
432 
433 template <class A, class B>
434 inline Tuple2<A, B> MakeTuple(const A& a, const B& b) {
435   return Tuple2<A, B>(a, b);
436 }
437 
438 template <class A, class B, class C>
439 inline Tuple3<A, B, C> MakeTuple(const A& a, const B& b, const C& c) {
440   return Tuple3<A, B, C>(a, b, c);
441 }
442 
443 template <class A, class B, class C, class D>
444 inline Tuple4<A, B, C, D> MakeTuple(const A& a, const B& b, const C& c,
445                                     const D& d) {
446   return Tuple4<A, B, C, D>(a, b, c, d);
447 }
448 
449 template <class A, class B, class C, class D, class E>
450 inline Tuple5<A, B, C, D, E> MakeTuple(const A& a, const B& b, const C& c,
451                                        const D& d, const E& e) {
452   return Tuple5<A, B, C, D, E>(a, b, c, d, e);
453 }
454 
455 template <class A, class B, class C, class D, class E, class F>
456 inline Tuple6<A, B, C, D, E, F> MakeTuple(const A& a, const B& b, const C& c,
457                                           const D& d, const E& e, const F& f) {
458   return Tuple6<A, B, C, D, E, F>(a, b, c, d, e, f);
459 }
460 
461 template <class A, class B, class C, class D, class E, class F, class G>
462 inline Tuple7<A, B, C, D, E, F, G> MakeTuple(const A& a, const B& b, const C& c,
463                                              const D& d, const E& e, const F& f,
464                                              const G& g) {
465   return Tuple7<A, B, C, D, E, F, G>(a, b, c, d, e, f, g);
466 }
467 
468 template <class A, class B, class C, class D, class E, class F, class G,
469           class H>
470 inline Tuple8<A, B, C, D, E, F, G, H> MakeTuple(const A& a, const B& b,
471                                                 const C& c, const D& d,
472                                                 const E& e, const F& f,
473                                                 const G& g, const H& h) {
474   return Tuple8<A, B, C, D, E, F, G, H>(a, b, c, d, e, f, g, h);
475 }
476 
477 // The following set of helpers make what Boost refers to as "Tiers" - a tuple
478 // of references.
479 
480 template <class A>
481 inline Tuple1<A&> MakeRefTuple(A& a) {
482   return Tuple1<A&>(a);
483 }
484 
485 template <class A, class B>
486 inline Tuple2<A&, B&> MakeRefTuple(A& a, B& b) {
487   return Tuple2<A&, B&>(a, b);
488 }
489 
490 template <class A, class B, class C>
491 inline Tuple3<A&, B&, C&> MakeRefTuple(A& a, B& b, C& c) {
492   return Tuple3<A&, B&, C&>(a, b, c);
493 }
494 
495 template <class A, class B, class C, class D>
496 inline Tuple4<A&, B&, C&, D&> MakeRefTuple(A& a, B& b, C& c, D& d) {
497   return Tuple4<A&, B&, C&, D&>(a, b, c, d);
498 }
499 
500 template <class A, class B, class C, class D, class E>
501 inline Tuple5<A&, B&, C&, D&, E&> MakeRefTuple(A& a, B& b, C& c, D& d, E& e) {
502   return Tuple5<A&, B&, C&, D&, E&>(a, b, c, d, e);
503 }
504 
505 template <class A, class B, class C, class D, class E, class F>
506 inline Tuple6<A&, B&, C&, D&, E&, F&> MakeRefTuple(A& a, B& b, C& c, D& d, E& e,
507                                                    F& f) {
508   return Tuple6<A&, B&, C&, D&, E&, F&>(a, b, c, d, e, f);
509 }
510 
511 template <class A, class B, class C, class D, class E, class F, class G>
512 inline Tuple7<A&, B&, C&, D&, E&, F&, G&> MakeRefTuple(A& a, B& b, C& c, D& d,
513                                                        E& e, F& f, G& g) {
514   return Tuple7<A&, B&, C&, D&, E&, F&, G&>(a, b, c, d, e, f, g);
515 }
516 
517 template <class A, class B, class C, class D, class E, class F, class G,
518           class H>
519 inline Tuple8<A&, B&, C&, D&, E&, F&, G&, H&> MakeRefTuple(A& a, B& b, C& c,
520                                                            D& d, E& e, F& f,
521                                                            G& g, H& h) {
522   return Tuple8<A&, B&, C&, D&, E&, F&, G&, H&>(a, b, c, d, e, f, g, h);
523 }
524 
525 // Dispatchers ----------------------------------------------------------------
526 //
527 // Helper functions that call the given method on an object, with the unpacked
528 // tuple arguments.  Notice that they all have the same number of arguments,
529 // so you need only write:
530 //   DispatchToMethod(object, &Object::method, args);
531 // This is very useful for templated dispatchers, since they don't need to know
532 // what type |args| is.
533 
534 // Non-Static Dispatchers with no out params.
535 
536 template <class ObjT, class Method>
537 inline void DispatchToMethod(ObjT* obj, Method method, const Tuple0& arg) {
538   (obj->*method)();
539 }
540 
541 template <class ObjT, class Method, class A>
542 inline void DispatchToMethod(ObjT* obj, Method method, const A& arg) {
543   (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg));
544 }
545 
546 template <class ObjT, class Method, class A>
547 inline void DispatchToMethod(ObjT* obj, Method method, const Tuple1<A>& arg) {
548   (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a));
549 }
550 
551 template<class ObjT, class Method, class A, class B>
552 inline void DispatchToMethod(ObjT* obj,
553                              Method method,
554                              const Tuple2<A, B>& arg) {
555   (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
556                  base::internal::UnwrapTraits<B>::Unwrap(arg.b));
557 }
558 
559 template<class ObjT, class Method, class A, class B, class C>
560 inline void DispatchToMethod(ObjT* obj, Method method,
561                              const Tuple3<A, B, C>& arg) {
562   (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
563                  base::internal::UnwrapTraits<B>::Unwrap(arg.b),
564                  base::internal::UnwrapTraits<C>::Unwrap(arg.c));
565 }
566 
567 template<class ObjT, class Method, class A, class B, class C, class D>
568 inline void DispatchToMethod(ObjT* obj, Method method,
569                              const Tuple4<A, B, C, D>& arg) {
570   (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
571                  base::internal::UnwrapTraits<B>::Unwrap(arg.b),
572                  base::internal::UnwrapTraits<C>::Unwrap(arg.c),
573                  base::internal::UnwrapTraits<D>::Unwrap(arg.d));
574 }
575 
576 template<class ObjT, class Method, class A, class B, class C, class D, class E>
577 inline void DispatchToMethod(ObjT* obj, Method method,
578                              const Tuple5<A, B, C, D, E>& arg) {
579   (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
580                  base::internal::UnwrapTraits<B>::Unwrap(arg.b),
581                  base::internal::UnwrapTraits<C>::Unwrap(arg.c),
582                  base::internal::UnwrapTraits<D>::Unwrap(arg.d),
583                  base::internal::UnwrapTraits<E>::Unwrap(arg.e));
584 }
585 
586 template<class ObjT, class Method, class A, class B, class C, class D, class E,
587          class F>
588 inline void DispatchToMethod(ObjT* obj, Method method,
589                              const Tuple6<A, B, C, D, E, F>& arg) {
590   (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
591                  base::internal::UnwrapTraits<B>::Unwrap(arg.b),
592                  base::internal::UnwrapTraits<C>::Unwrap(arg.c),
593                  base::internal::UnwrapTraits<D>::Unwrap(arg.d),
594                  base::internal::UnwrapTraits<E>::Unwrap(arg.e),
595                  base::internal::UnwrapTraits<F>::Unwrap(arg.f));
596 }
597 
598 template<class ObjT, class Method, class A, class B, class C, class D, class E,
599          class F, class G>
600 inline void DispatchToMethod(ObjT* obj, Method method,
601                              const Tuple7<A, B, C, D, E, F, G>& arg) {
602   (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
603                  base::internal::UnwrapTraits<B>::Unwrap(arg.b),
604                  base::internal::UnwrapTraits<C>::Unwrap(arg.c),
605                  base::internal::UnwrapTraits<D>::Unwrap(arg.d),
606                  base::internal::UnwrapTraits<E>::Unwrap(arg.e),
607                  base::internal::UnwrapTraits<F>::Unwrap(arg.f),
608                  base::internal::UnwrapTraits<G>::Unwrap(arg.g));
609 }
610 
611 template<class ObjT, class Method, class A, class B, class C, class D, class E,
612          class F, class G, class H>
613 inline void DispatchToMethod(ObjT* obj, Method method,
614                              const Tuple8<A, B, C, D, E, F, G, H>& arg) {
615   (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
616                  base::internal::UnwrapTraits<B>::Unwrap(arg.b),
617                  base::internal::UnwrapTraits<C>::Unwrap(arg.c),
618                  base::internal::UnwrapTraits<D>::Unwrap(arg.d),
619                  base::internal::UnwrapTraits<E>::Unwrap(arg.e),
620                  base::internal::UnwrapTraits<F>::Unwrap(arg.f),
621                  base::internal::UnwrapTraits<G>::Unwrap(arg.g),
622                  base::internal::UnwrapTraits<H>::Unwrap(arg.h));
623 }
624 
625 // Static Dispatchers with no out params.
626 
627 template <class Function>
628 inline void DispatchToFunction(Function function, const Tuple0& arg) {
629   (*function)();
630 }
631 
632 template <class Function, class A>
633 inline void DispatchToFunction(Function function, const A& arg) {
634   (*function)(arg);
635 }
636 
637 template <class Function, class A>
638 inline void DispatchToFunction(Function function, const Tuple1<A>& arg) {
639   (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a));
640 }
641 
642 template<class Function, class A, class B>
643 inline void DispatchToFunction(Function function, const Tuple2<A, B>& arg) {
644   (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
645               base::internal::UnwrapTraits<B>::Unwrap(arg.b));
646 }
647 
648 template<class Function, class A, class B, class C>
649 inline void DispatchToFunction(Function function, const Tuple3<A, B, C>& arg) {
650   (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
651               base::internal::UnwrapTraits<B>::Unwrap(arg.b),
652               base::internal::UnwrapTraits<C>::Unwrap(arg.c));
653 }
654 
655 template<class Function, class A, class B, class C, class D>
656 inline void DispatchToFunction(Function function,
657                                const Tuple4<A, B, C, D>& arg) {
658   (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
659               base::internal::UnwrapTraits<B>::Unwrap(arg.b),
660               base::internal::UnwrapTraits<C>::Unwrap(arg.c),
661               base::internal::UnwrapTraits<D>::Unwrap(arg.d));
662 }
663 
664 template<class Function, class A, class B, class C, class D, class E>
665 inline void DispatchToFunction(Function function,
666                                const Tuple5<A, B, C, D, E>& arg) {
667   (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
668               base::internal::UnwrapTraits<B>::Unwrap(arg.b),
669               base::internal::UnwrapTraits<C>::Unwrap(arg.c),
670               base::internal::UnwrapTraits<D>::Unwrap(arg.d),
671               base::internal::UnwrapTraits<E>::Unwrap(arg.e));
672 }
673 
674 template<class Function, class A, class B, class C, class D, class E, class F>
675 inline void DispatchToFunction(Function function,
676                                const Tuple6<A, B, C, D, E, F>& arg) {
677   (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
678               base::internal::UnwrapTraits<B>::Unwrap(arg.b),
679               base::internal::UnwrapTraits<C>::Unwrap(arg.c),
680               base::internal::UnwrapTraits<D>::Unwrap(arg.d),
681               base::internal::UnwrapTraits<E>::Unwrap(arg.e),
682               base::internal::UnwrapTraits<F>::Unwrap(arg.f));
683 }
684 
685 template<class Function, class A, class B, class C, class D, class E, class F,
686          class G>
687 inline void DispatchToFunction(Function function,
688                                const Tuple7<A, B, C, D, E, F, G>& arg) {
689   (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
690               base::internal::UnwrapTraits<B>::Unwrap(arg.b),
691               base::internal::UnwrapTraits<C>::Unwrap(arg.c),
692               base::internal::UnwrapTraits<D>::Unwrap(arg.d),
693               base::internal::UnwrapTraits<E>::Unwrap(arg.e),
694               base::internal::UnwrapTraits<F>::Unwrap(arg.f),
695               base::internal::UnwrapTraits<G>::Unwrap(arg.g));
696 }
697 
698 template<class Function, class A, class B, class C, class D, class E, class F,
699          class G, class H>
700 inline void DispatchToFunction(Function function,
701                                const Tuple8<A, B, C, D, E, F, G, H>& arg) {
702   (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
703               base::internal::UnwrapTraits<B>::Unwrap(arg.b),
704               base::internal::UnwrapTraits<C>::Unwrap(arg.c),
705               base::internal::UnwrapTraits<D>::Unwrap(arg.d),
706               base::internal::UnwrapTraits<E>::Unwrap(arg.e),
707               base::internal::UnwrapTraits<F>::Unwrap(arg.f),
708               base::internal::UnwrapTraits<G>::Unwrap(arg.g),
709               base::internal::UnwrapTraits<H>::Unwrap(arg.h));
710 }
711 
712 // Dispatchers with 0 out param (as a Tuple0).
713 
714 template <class ObjT, class Method>
715 inline void DispatchToMethod(ObjT* obj,
716                              Method method,
717                              const Tuple0& arg, Tuple0*) {
718   (obj->*method)();
719 }
720 
721 template <class ObjT, class Method, class A>
722 inline void DispatchToMethod(ObjT* obj, Method method, const A& arg, Tuple0*) {
723   (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg));
724 }
725 
726 template <class ObjT, class Method, class A>
727 inline void DispatchToMethod(ObjT* obj,
728                              Method method,
729                              const Tuple1<A>& arg, Tuple0*) {
730   (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a));
731 }
732 
733 template<class ObjT, class Method, class A, class B>
734 inline void DispatchToMethod(ObjT* obj,
735                              Method method,
736                              const Tuple2<A, B>& arg, Tuple0*) {
737   (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
738                  base::internal::UnwrapTraits<B>::Unwrap(arg.b));
739 }
740 
741 template<class ObjT, class Method, class A, class B, class C>
742 inline void DispatchToMethod(ObjT* obj, Method method,
743                              const Tuple3<A, B, C>& arg, Tuple0*) {
744   (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
745                  base::internal::UnwrapTraits<B>::Unwrap(arg.b),
746                  base::internal::UnwrapTraits<C>::Unwrap(arg.c));
747 }
748 
749 template<class ObjT, class Method, class A, class B, class C, class D>
750 inline void DispatchToMethod(ObjT* obj, Method method,
751                              const Tuple4<A, B, C, D>& arg, Tuple0*) {
752   (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
753                  base::internal::UnwrapTraits<B>::Unwrap(arg.b),
754                  base::internal::UnwrapTraits<C>::Unwrap(arg.c),
755                  base::internal::UnwrapTraits<D>::Unwrap(arg.d));
756 }
757 
758 template<class ObjT, class Method, class A, class B, class C, class D, class E>
759 inline void DispatchToMethod(ObjT* obj, Method method,
760                              const Tuple5<A, B, C, D, E>& arg, Tuple0*) {
761   (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
762                  base::internal::UnwrapTraits<B>::Unwrap(arg.b),
763                  base::internal::UnwrapTraits<C>::Unwrap(arg.c),
764                  base::internal::UnwrapTraits<D>::Unwrap(arg.d),
765                  base::internal::UnwrapTraits<E>::Unwrap(arg.e));
766 }
767 
768 template<class ObjT, class Method, class A, class B, class C, class D, class E,
769          class F>
770 inline void DispatchToMethod(ObjT* obj, Method method,
771                              const Tuple6<A, B, C, D, E, F>& arg, Tuple0*) {
772   (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
773                  base::internal::UnwrapTraits<B>::Unwrap(arg.b),
774                  base::internal::UnwrapTraits<C>::Unwrap(arg.c),
775                  base::internal::UnwrapTraits<D>::Unwrap(arg.d),
776                  base::internal::UnwrapTraits<E>::Unwrap(arg.e),
777                  base::internal::UnwrapTraits<F>::Unwrap(arg.f));
778 }
779 
780 // Dispatchers with 1 out param.
781 
782 template<class ObjT, class Method,
783          class OutA>
784 inline void DispatchToMethod(ObjT* obj, Method method,
785                              const Tuple0& in,
786                              Tuple1<OutA>* out) {
787   (obj->*method)(&out->a);
788 }
789 
790 template<class ObjT, class Method, class InA,
791          class OutA>
792 inline void DispatchToMethod(ObjT* obj, Method method,
793                              const InA& in,
794                              Tuple1<OutA>* out) {
795   (obj->*method)(in, &out->a);
796 }
797 
798 template<class ObjT, class Method, class InA,
799          class OutA>
800 inline void DispatchToMethod(ObjT* obj, Method method,
801                              const Tuple1<InA>& in,
802                              Tuple1<OutA>* out) {
803   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), &out->a);
804 }
805 
806 template<class ObjT, class Method, class InA, class InB,
807          class OutA>
808 inline void DispatchToMethod(ObjT* obj, Method method,
809                              const Tuple2<InA, InB>& in,
810                              Tuple1<OutA>* out) {
811   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
812                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
813                  &out->a);
814 }
815 
816 template<class ObjT, class Method, class InA, class InB, class InC,
817          class OutA>
818 inline void DispatchToMethod(ObjT* obj, Method method,
819                              const Tuple3<InA, InB, InC>& in,
820                              Tuple1<OutA>* out) {
821   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
822                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
823                  base::internal::UnwrapTraits<InC>::Unwrap(in.c),
824                  &out->a);
825 }
826 
827 template<class ObjT, class Method, class InA, class InB, class InC, class InD,
828          class OutA>
829 inline void DispatchToMethod(ObjT* obj, Method method,
830                              const Tuple4<InA, InB, InC, InD>& in,
831                              Tuple1<OutA>* out) {
832   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
833                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
834                  base::internal::UnwrapTraits<InC>::Unwrap(in.c),
835                  base::internal::UnwrapTraits<InD>::Unwrap(in.d),
836                  &out->a);
837 }
838 
839 template<class ObjT, class Method, class InA, class InB, class InC, class InD,
840          class InE, class OutA>
841 inline void DispatchToMethod(ObjT* obj, Method method,
842                              const Tuple5<InA, InB, InC, InD, InE>& in,
843                              Tuple1<OutA>* out) {
844   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
845                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
846                  base::internal::UnwrapTraits<InC>::Unwrap(in.c),
847                  base::internal::UnwrapTraits<InD>::Unwrap(in.d),
848                  base::internal::UnwrapTraits<InE>::Unwrap(in.e),
849                  &out->a);
850 }
851 
852 template<class ObjT, class Method,
853          class InA, class InB, class InC, class InD, class InE, class InF,
854          class OutA>
855 inline void DispatchToMethod(ObjT* obj, Method method,
856                              const Tuple6<InA, InB, InC, InD, InE, InF>& in,
857                              Tuple1<OutA>* out) {
858   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
859                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
860                  base::internal::UnwrapTraits<InC>::Unwrap(in.c),
861                  base::internal::UnwrapTraits<InD>::Unwrap(in.d),
862                  base::internal::UnwrapTraits<InE>::Unwrap(in.e),
863                  base::internal::UnwrapTraits<InF>::Unwrap(in.f),
864                  &out->a);
865 }
866 
867 // Dispatchers with 2 out params.
868 
869 template<class ObjT, class Method,
870          class OutA, class OutB>
871 inline void DispatchToMethod(ObjT* obj, Method method,
872                              const Tuple0& in,
873                              Tuple2<OutA, OutB>* out) {
874   (obj->*method)(&out->a, &out->b);
875 }
876 
877 template<class ObjT, class Method, class InA,
878          class OutA, class OutB>
879 inline void DispatchToMethod(ObjT* obj, Method method,
880                              const InA& in,
881                              Tuple2<OutA, OutB>* out) {
882   (obj->*method)(in, &out->a, &out->b);
883 }
884 
885 template<class ObjT, class Method, class InA,
886          class OutA, class OutB>
887 inline void DispatchToMethod(ObjT* obj, Method method,
888                              const Tuple1<InA>& in,
889                              Tuple2<OutA, OutB>* out) {
890   (obj->*method)(
891       base::internal::UnwrapTraits<InA>::Unwrap(in.a), &out->a, &out->b);
892 }
893 
894 template<class ObjT, class Method, class InA, class InB,
895          class OutA, class OutB>
896 inline void DispatchToMethod(ObjT* obj, Method method,
897                              const Tuple2<InA, InB>& in,
898                              Tuple2<OutA, OutB>* out) {
899   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
900                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
901                  &out->a,
902                  &out->b);
903 }
904 
905 template<class ObjT, class Method, class InA, class InB, class InC,
906          class OutA, class OutB>
907 inline void DispatchToMethod(ObjT* obj, Method method,
908                              const Tuple3<InA, InB, InC>& in,
909                              Tuple2<OutA, OutB>* out) {
910   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
911                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
912                  base::internal::UnwrapTraits<InC>::Unwrap(in.c),
913                  &out->a,
914                  &out->b);
915 }
916 
917 template<class ObjT, class Method, class InA, class InB, class InC, class InD,
918          class OutA, class OutB>
919 inline void DispatchToMethod(ObjT* obj, Method method,
920                              const Tuple4<InA, InB, InC, InD>& in,
921                              Tuple2<OutA, OutB>* out) {
922   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
923                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
924                  base::internal::UnwrapTraits<InC>::Unwrap(in.c),
925                  base::internal::UnwrapTraits<InD>::Unwrap(in.d),
926                  &out->a,
927                  &out->b);
928 }
929 
930 template<class ObjT, class Method,
931          class InA, class InB, class InC, class InD, class InE,
932          class OutA, class OutB>
933 inline void DispatchToMethod(ObjT* obj, Method method,
934                              const Tuple5<InA, InB, InC, InD, InE>& in,
935                              Tuple2<OutA, OutB>* out) {
936   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
937                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
938                  base::internal::UnwrapTraits<InC>::Unwrap(in.c),
939                  base::internal::UnwrapTraits<InD>::Unwrap(in.d),
940                  base::internal::UnwrapTraits<InE>::Unwrap(in.e),
941                  &out->a,
942                  &out->b);
943 }
944 
945 template<class ObjT, class Method,
946          class InA, class InB, class InC, class InD, class InE, class InF,
947          class OutA, class OutB>
948 inline void DispatchToMethod(ObjT* obj, Method method,
949                              const Tuple6<InA, InB, InC, InD, InE, InF>& in,
950                              Tuple2<OutA, OutB>* out) {
951   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
952                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
953                  base::internal::UnwrapTraits<InC>::Unwrap(in.c),
954                  base::internal::UnwrapTraits<InD>::Unwrap(in.d),
955                  base::internal::UnwrapTraits<InE>::Unwrap(in.e),
956                  base::internal::UnwrapTraits<InF>::Unwrap(in.f),
957                  &out->a,
958                  &out->b);
959 }
960 
961 // Dispatchers with 3 out params.
962 
963 template<class ObjT, class Method,
964          class OutA, class OutB, class OutC>
965 inline void DispatchToMethod(ObjT* obj, Method method,
966                              const Tuple0& in,
967                              Tuple3<OutA, OutB, OutC>* out) {
968   (obj->*method)(&out->a, &out->b, &out->c);
969 }
970 
971 template<class ObjT, class Method, class InA,
972          class OutA, class OutB, class OutC>
973 inline void DispatchToMethod(ObjT* obj, Method method,
974                              const InA& in,
975                              Tuple3<OutA, OutB, OutC>* out) {
976   (obj->*method)(in, &out->a, &out->b, &out->c);
977 }
978 
979 template<class ObjT, class Method, class InA,
980          class OutA, class OutB, class OutC>
981 inline void DispatchToMethod(ObjT* obj, Method method,
982                              const Tuple1<InA>& in,
983                              Tuple3<OutA, OutB, OutC>* out) {
984   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
985                  &out->a,
986                  &out->b,
987                  &out->c);
988 }
989 
990 template<class ObjT, class Method, class InA, class InB,
991          class OutA, class OutB, class OutC>
992 inline void DispatchToMethod(ObjT* obj, Method method,
993                              const Tuple2<InA, InB>& in,
994                              Tuple3<OutA, OutB, OutC>* out) {
995   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
996                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
997                  &out->a,
998                  &out->b,
999                  &out->c);
1000 }
1001 
1002 template<class ObjT, class Method, class InA, class InB, class InC,
1003          class OutA, class OutB, class OutC>
1004 inline void DispatchToMethod(ObjT* obj, Method method,
1005                              const Tuple3<InA, InB, InC>& in,
1006                              Tuple3<OutA, OutB, OutC>* out) {
1007   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
1008                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
1009                  base::internal::UnwrapTraits<InC>::Unwrap(in.c),
1010                  &out->a,
1011                  &out->b,
1012                  &out->c);
1013 }
1014 
1015 template<class ObjT, class Method, class InA, class InB, class InC, class InD,
1016          class OutA, class OutB, class OutC>
1017 inline void DispatchToMethod(ObjT* obj, Method method,
1018                              const Tuple4<InA, InB, InC, InD>& in,
1019                              Tuple3<OutA, OutB, OutC>* out) {
1020   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
1021                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
1022                  base::internal::UnwrapTraits<InC>::Unwrap(in.c),
1023                  base::internal::UnwrapTraits<InD>::Unwrap(in.d),
1024                  &out->a,
1025                  &out->b,
1026                  &out->c);
1027 }
1028 
1029 template<class ObjT, class Method,
1030          class InA, class InB, class InC, class InD, class InE,
1031          class OutA, class OutB, class OutC>
1032 inline void DispatchToMethod(ObjT* obj, Method method,
1033                              const Tuple5<InA, InB, InC, InD, InE>& in,
1034                              Tuple3<OutA, OutB, OutC>* out) {
1035   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
1036                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
1037                  base::internal::UnwrapTraits<InC>::Unwrap(in.c),
1038                  base::internal::UnwrapTraits<InD>::Unwrap(in.d),
1039                  base::internal::UnwrapTraits<InE>::Unwrap(in.e),
1040                  &out->a,
1041                  &out->b,
1042                  &out->c);
1043 }
1044 
1045 template<class ObjT, class Method,
1046          class InA, class InB, class InC, class InD, class InE, class InF,
1047          class OutA, class OutB, class OutC>
1048 inline void DispatchToMethod(ObjT* obj, Method method,
1049                              const Tuple6<InA, InB, InC, InD, InE, InF>& in,
1050                              Tuple3<OutA, OutB, OutC>* out) {
1051   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
1052                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
1053                  base::internal::UnwrapTraits<InC>::Unwrap(in.c),
1054                  base::internal::UnwrapTraits<InD>::Unwrap(in.d),
1055                  base::internal::UnwrapTraits<InE>::Unwrap(in.e),
1056                  base::internal::UnwrapTraits<InF>::Unwrap(in.f),
1057                  &out->a,
1058                  &out->b,
1059                  &out->c);
1060 }
1061 
1062 // Dispatchers with 4 out params.
1063 
1064 template<class ObjT, class Method,
1065          class OutA, class OutB, class OutC, class OutD>
1066 inline void DispatchToMethod(ObjT* obj, Method method,
1067                              const Tuple0& in,
1068                              Tuple4<OutA, OutB, OutC, OutD>* out) {
1069   (obj->*method)(&out->a, &out->b, &out->c, &out->d);
1070 }
1071 
1072 template<class ObjT, class Method, class InA,
1073          class OutA, class OutB, class OutC, class OutD>
1074 inline void DispatchToMethod(ObjT* obj, Method method,
1075                              const InA& in,
1076                              Tuple4<OutA, OutB, OutC, OutD>* out) {
1077   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in),
1078                  &out->a,
1079                  &out->b,
1080                  &out->c,
1081                  &out->d);
1082 }
1083 
1084 template<class ObjT, class Method, class InA,
1085          class OutA, class OutB, class OutC, class OutD>
1086 inline void DispatchToMethod(ObjT* obj, Method method,
1087                              const Tuple1<InA>& in,
1088                              Tuple4<OutA, OutB, OutC, OutD>* out) {
1089   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
1090                  &out->a,
1091                  &out->b,
1092                  &out->c,
1093                  &out->d);
1094 }
1095 
1096 template<class ObjT, class Method, class InA, class InB,
1097          class OutA, class OutB, class OutC, class OutD>
1098 inline void DispatchToMethod(ObjT* obj, Method method,
1099                              const Tuple2<InA, InB>& in,
1100                              Tuple4<OutA, OutB, OutC, OutD>* out) {
1101   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
1102                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
1103                  &out->a,
1104                  &out->b,
1105                  &out->c,
1106                  &out->d);
1107 }
1108 
1109 template<class ObjT, class Method, class InA, class InB, class InC,
1110          class OutA, class OutB, class OutC, class OutD>
1111 inline void DispatchToMethod(ObjT* obj, Method method,
1112                              const Tuple3<InA, InB, InC>& in,
1113                              Tuple4<OutA, OutB, OutC, OutD>* out) {
1114   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
1115                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
1116                  base::internal::UnwrapTraits<InC>::Unwrap(in.c),
1117                  &out->a,
1118                  &out->b,
1119                  &out->c,
1120                  &out->d);
1121 }
1122 
1123 template<class ObjT, class Method, class InA, class InB, class InC, class InD,
1124          class OutA, class OutB, class OutC, class OutD>
1125 inline void DispatchToMethod(ObjT* obj, Method method,
1126                              const Tuple4<InA, InB, InC, InD>& in,
1127                              Tuple4<OutA, OutB, OutC, OutD>* out) {
1128   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
1129                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
1130                  base::internal::UnwrapTraits<InC>::Unwrap(in.c),
1131                  base::internal::UnwrapTraits<InD>::Unwrap(in.d),
1132                  &out->a,
1133                  &out->b,
1134                  &out->c,
1135                  &out->d);
1136 }
1137 
1138 template<class ObjT, class Method,
1139          class InA, class InB, class InC, class InD, class InE,
1140          class OutA, class OutB, class OutC, class OutD>
1141 inline void DispatchToMethod(ObjT* obj, Method method,
1142                              const Tuple5<InA, InB, InC, InD, InE>& in,
1143                              Tuple4<OutA, OutB, OutC, OutD>* out) {
1144   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
1145                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
1146                  base::internal::UnwrapTraits<InC>::Unwrap(in.c),
1147                  base::internal::UnwrapTraits<InD>::Unwrap(in.d),
1148                  base::internal::UnwrapTraits<InE>::Unwrap(in.e),
1149                  &out->a,
1150                  &out->b,
1151                  &out->c,
1152                  &out->d);
1153 }
1154 
1155 template<class ObjT, class Method,
1156          class InA, class InB, class InC, class InD, class InE, class InF,
1157          class OutA, class OutB, class OutC, class OutD>
1158 inline void DispatchToMethod(ObjT* obj, Method method,
1159                              const Tuple6<InA, InB, InC, InD, InE, InF>& in,
1160                              Tuple4<OutA, OutB, OutC, OutD>* out) {
1161   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
1162                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
1163                  base::internal::UnwrapTraits<InC>::Unwrap(in.c),
1164                  base::internal::UnwrapTraits<InD>::Unwrap(in.d),
1165                  base::internal::UnwrapTraits<InE>::Unwrap(in.e),
1166                  base::internal::UnwrapTraits<InF>::Unwrap(in.f),
1167                  &out->a,
1168                  &out->b,
1169                  &out->c,
1170                  &out->d);
1171 }
1172 
1173 // Dispatchers with 5 out params.
1174 
1175 template<class ObjT, class Method,
1176          class OutA, class OutB, class OutC, class OutD, class OutE>
1177 inline void DispatchToMethod(ObjT* obj, Method method,
1178                              const Tuple0& in,
1179                              Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
1180   (obj->*method)(&out->a, &out->b, &out->c, &out->d, &out->e);
1181 }
1182 
1183 template<class ObjT, class Method, class InA,
1184          class OutA, class OutB, class OutC, class OutD, class OutE>
1185 inline void DispatchToMethod(ObjT* obj, Method method,
1186                              const InA& in,
1187                              Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
1188   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in),
1189                  &out->a,
1190                  &out->b,
1191                  &out->c,
1192                  &out->d,
1193                  &out->e);
1194 }
1195 
1196 template<class ObjT, class Method, class InA,
1197          class OutA, class OutB, class OutC, class OutD, class OutE>
1198 inline void DispatchToMethod(ObjT* obj, Method method,
1199                              const Tuple1<InA>& in,
1200                              Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
1201   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
1202                  &out->a,
1203                  &out->b,
1204                  &out->c,
1205                  &out->d,
1206                  &out->e);
1207 }
1208 
1209 template<class ObjT, class Method, class InA, class InB,
1210          class OutA, class OutB, class OutC, class OutD, class OutE>
1211 inline void DispatchToMethod(ObjT* obj, Method method,
1212                              const Tuple2<InA, InB>& in,
1213                              Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
1214   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
1215                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
1216                  &out->a,
1217                  &out->b,
1218                  &out->c,
1219                  &out->d,
1220                  &out->e);
1221 }
1222 
1223 template<class ObjT, class Method, class InA, class InB, class InC,
1224          class OutA, class OutB, class OutC, class OutD, class OutE>
1225 inline void DispatchToMethod(ObjT* obj, Method method,
1226                              const Tuple3<InA, InB, InC>& in,
1227                              Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
1228   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
1229                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
1230                  base::internal::UnwrapTraits<InC>::Unwrap(in.c),
1231                  &out->a,
1232                  &out->b,
1233                  &out->c,
1234                  &out->d,
1235                  &out->e);
1236 }
1237 
1238 template<class ObjT, class Method, class InA, class InB, class InC, class InD,
1239          class OutA, class OutB, class OutC, class OutD, class OutE>
1240 inline void DispatchToMethod(ObjT* obj, Method method,
1241                              const Tuple4<InA, InB, InC, InD>& in,
1242                              Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
1243   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
1244                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
1245                  base::internal::UnwrapTraits<InC>::Unwrap(in.c),
1246                  base::internal::UnwrapTraits<InD>::Unwrap(in.d),
1247                  &out->a,
1248                  &out->b,
1249                  &out->c,
1250                  &out->d,
1251                  &out->e);
1252 }
1253 
1254 template<class ObjT, class Method,
1255          class InA, class InB, class InC, class InD, class InE,
1256          class OutA, class OutB, class OutC, class OutD, class OutE>
1257 inline void DispatchToMethod(ObjT* obj, Method method,
1258                              const Tuple5<InA, InB, InC, InD, InE>& in,
1259                              Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
1260   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
1261                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
1262                  base::internal::UnwrapTraits<InC>::Unwrap(in.c),
1263                  base::internal::UnwrapTraits<InD>::Unwrap(in.d),
1264                  base::internal::UnwrapTraits<InE>::Unwrap(in.e),
1265                  &out->a,
1266                  &out->b,
1267                  &out->c,
1268                  &out->d,
1269                  &out->e);
1270 }
1271 
1272 template<class ObjT, class Method,
1273          class InA, class InB, class InC, class InD, class InE, class InF,
1274          class OutA, class OutB, class OutC, class OutD, class OutE>
1275 inline void DispatchToMethod(ObjT* obj, Method method,
1276                              const Tuple6<InA, InB, InC, InD, InE, InF>& in,
1277                              Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
1278   (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
1279                  base::internal::UnwrapTraits<InB>::Unwrap(in.b),
1280                  base::internal::UnwrapTraits<InC>::Unwrap(in.c),
1281                  base::internal::UnwrapTraits<InD>::Unwrap(in.d),
1282                  base::internal::UnwrapTraits<InE>::Unwrap(in.e),
1283                  base::internal::UnwrapTraits<InF>::Unwrap(in.f),
1284                  &out->a,
1285                  &out->b,
1286                  &out->c,
1287                  &out->d,
1288                  &out->e);
1289 }
1290 
1291 #endif  // BASE_TUPLE_H__
1292