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
42template <class P>
43struct TupleTraits {
44  typedef P ValueType;
45  typedef P& RefType;
46  typedef const P& ParamType;
47};
48
49template <class P>
50struct TupleTraits<P&> {
51  typedef P ValueType;
52  typedef P& RefType;
53  typedef P& ParamType;
54};
55
56template <class P>
57struct 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
73struct Tuple0 {
74  typedef Tuple0 ValueTuple;
75  typedef Tuple0 RefTuple;
76  typedef Tuple0 ParamTuple;
77};
78
79template <class A>
80struct 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
90template <class A, class B>
91struct 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
106template <class A, class B, class C>
107struct 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
125template <class A, class B, class C, class D>
126struct 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
147template <class A, class B, class C, class D, class E>
148struct 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
172template <class A, class B, class C, class D, class E, class F>
173struct 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
200template <class A, class B, class C, class D, class E, class F, class G>
201struct 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
231template <class A, class B, class C, class D, class E, class F, class G,
232          class H>
233struct 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
271template <>
272struct TupleTypes< Tuple0 > {
273  typedef Tuple0 ValueTuple;
274  typedef Tuple0 RefTuple;
275  typedef Tuple0 ParamTuple;
276};
277
278template <class A>
279struct 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
285template <class A, class B>
286struct TupleTypes< Tuple2<A, B> > {
287  typedef Tuple2<typename TupleTraits<A>::ValueType,
288                 typename TupleTraits<B>::ValueType> ValueTuple;
289typedef 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
295template <class A, class B, class C>
296struct TupleTypes< Tuple3<A, B, C> > {
297  typedef Tuple3<typename TupleTraits<A>::ValueType,
298                 typename TupleTraits<B>::ValueType,
299                 typename TupleTraits<C>::ValueType> ValueTuple;
300typedef 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
308template <class A, class B, class C, class D>
309struct 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;
314typedef 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
324template <class A, class B, class C, class D, class E>
325struct 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;
331typedef 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
343template <class A, class B, class C, class D, class E, class F>
344struct 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;
351typedef 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
365template <class A, class B, class C, class D, class E, class F, class G>
366struct 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;
374typedef 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
390template <class A, class B, class C, class D, class E, class F, class G,
391          class H>
392struct 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;
401typedef 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
424inline Tuple0 MakeTuple() {
425  return Tuple0();
426}
427
428template <class A>
429inline Tuple1<A> MakeTuple(const A& a) {
430  return Tuple1<A>(a);
431}
432
433template <class A, class B>
434inline Tuple2<A, B> MakeTuple(const A& a, const B& b) {
435  return Tuple2<A, B>(a, b);
436}
437
438template <class A, class B, class C>
439inline 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
443template <class A, class B, class C, class D>
444inline 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
449template <class A, class B, class C, class D, class E>
450inline 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
455template <class A, class B, class C, class D, class E, class F>
456inline 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
461template <class A, class B, class C, class D, class E, class F, class G>
462inline 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
468template <class A, class B, class C, class D, class E, class F, class G,
469          class H>
470inline 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
480template <class A>
481inline Tuple1<A&> MakeRefTuple(A& a) {
482  return Tuple1<A&>(a);
483}
484
485template <class A, class B>
486inline Tuple2<A&, B&> MakeRefTuple(A& a, B& b) {
487  return Tuple2<A&, B&>(a, b);
488}
489
490template <class A, class B, class C>
491inline Tuple3<A&, B&, C&> MakeRefTuple(A& a, B& b, C& c) {
492  return Tuple3<A&, B&, C&>(a, b, c);
493}
494
495template <class A, class B, class C, class D>
496inline 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
500template <class A, class B, class C, class D, class E>
501inline 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
505template <class A, class B, class C, class D, class E, class F>
506inline 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
511template <class A, class B, class C, class D, class E, class F, class G>
512inline 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
517template <class A, class B, class C, class D, class E, class F, class G,
518          class H>
519inline 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
536template <class ObjT, class Method>
537inline void DispatchToMethod(ObjT* obj, Method method, const Tuple0& arg) {
538  (obj->*method)();
539}
540
541template <class ObjT, class Method, class A>
542inline void DispatchToMethod(ObjT* obj, Method method, const A& arg) {
543  (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg));
544}
545
546template <class ObjT, class Method, class A>
547inline void DispatchToMethod(ObjT* obj, Method method, const Tuple1<A>& arg) {
548  (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a));
549}
550
551template<class ObjT, class Method, class A, class B>
552inline 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
559template<class ObjT, class Method, class A, class B, class C>
560inline 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
567template<class ObjT, class Method, class A, class B, class C, class D>
568inline 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
576template<class ObjT, class Method, class A, class B, class C, class D, class E>
577inline 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
586template<class ObjT, class Method, class A, class B, class C, class D, class E,
587         class F>
588inline 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
598template<class ObjT, class Method, class A, class B, class C, class D, class E,
599         class F, class G>
600inline 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
611template<class ObjT, class Method, class A, class B, class C, class D, class E,
612         class F, class G, class H>
613inline 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
627template <class Function>
628inline void DispatchToFunction(Function function, const Tuple0& arg) {
629  (*function)();
630}
631
632template <class Function, class A>
633inline void DispatchToFunction(Function function, const A& arg) {
634  (*function)(arg);
635}
636
637template <class Function, class A>
638inline void DispatchToFunction(Function function, const Tuple1<A>& arg) {
639  (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a));
640}
641
642template<class Function, class A, class B>
643inline 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
648template<class Function, class A, class B, class C>
649inline 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
655template<class Function, class A, class B, class C, class D>
656inline 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
664template<class Function, class A, class B, class C, class D, class E>
665inline 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
674template<class Function, class A, class B, class C, class D, class E, class F>
675inline 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
685template<class Function, class A, class B, class C, class D, class E, class F,
686         class G>
687inline 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
698template<class Function, class A, class B, class C, class D, class E, class F,
699         class G, class H>
700inline 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
714template <class ObjT, class Method>
715inline void DispatchToMethod(ObjT* obj,
716                             Method method,
717                             const Tuple0& arg, Tuple0*) {
718  (obj->*method)();
719}
720
721template <class ObjT, class Method, class A>
722inline void DispatchToMethod(ObjT* obj, Method method, const A& arg, Tuple0*) {
723  (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg));
724}
725
726template <class ObjT, class Method, class A>
727inline 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
733template<class ObjT, class Method, class A, class B>
734inline 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
741template<class ObjT, class Method, class A, class B, class C>
742inline 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
749template<class ObjT, class Method, class A, class B, class C, class D>
750inline 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
758template<class ObjT, class Method, class A, class B, class C, class D, class E>
759inline 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
768template<class ObjT, class Method, class A, class B, class C, class D, class E,
769         class F>
770inline 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
782template<class ObjT, class Method,
783         class OutA>
784inline void DispatchToMethod(ObjT* obj, Method method,
785                             const Tuple0& in,
786                             Tuple1<OutA>* out) {
787  (obj->*method)(&out->a);
788}
789
790template<class ObjT, class Method, class InA,
791         class OutA>
792inline void DispatchToMethod(ObjT* obj, Method method,
793                             const InA& in,
794                             Tuple1<OutA>* out) {
795  (obj->*method)(in, &out->a);
796}
797
798template<class ObjT, class Method, class InA,
799         class OutA>
800inline 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
806template<class ObjT, class Method, class InA, class InB,
807         class OutA>
808inline 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
816template<class ObjT, class Method, class InA, class InB, class InC,
817         class OutA>
818inline 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
827template<class ObjT, class Method, class InA, class InB, class InC, class InD,
828         class OutA>
829inline 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
839template<class ObjT, class Method, class InA, class InB, class InC, class InD,
840         class InE, class OutA>
841inline 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
852template<class ObjT, class Method,
853         class InA, class InB, class InC, class InD, class InE, class InF,
854         class OutA>
855inline 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
869template<class ObjT, class Method,
870         class OutA, class OutB>
871inline void DispatchToMethod(ObjT* obj, Method method,
872                             const Tuple0& in,
873                             Tuple2<OutA, OutB>* out) {
874  (obj->*method)(&out->a, &out->b);
875}
876
877template<class ObjT, class Method, class InA,
878         class OutA, class OutB>
879inline 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
885template<class ObjT, class Method, class InA,
886         class OutA, class OutB>
887inline 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
894template<class ObjT, class Method, class InA, class InB,
895         class OutA, class OutB>
896inline 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
905template<class ObjT, class Method, class InA, class InB, class InC,
906         class OutA, class OutB>
907inline 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
917template<class ObjT, class Method, class InA, class InB, class InC, class InD,
918         class OutA, class OutB>
919inline 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
930template<class ObjT, class Method,
931         class InA, class InB, class InC, class InD, class InE,
932         class OutA, class OutB>
933inline 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
945template<class ObjT, class Method,
946         class InA, class InB, class InC, class InD, class InE, class InF,
947         class OutA, class OutB>
948inline 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
963template<class ObjT, class Method,
964         class OutA, class OutB, class OutC>
965inline 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
971template<class ObjT, class Method, class InA,
972         class OutA, class OutB, class OutC>
973inline 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
979template<class ObjT, class Method, class InA,
980         class OutA, class OutB, class OutC>
981inline 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
990template<class ObjT, class Method, class InA, class InB,
991         class OutA, class OutB, class OutC>
992inline 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
1002template<class ObjT, class Method, class InA, class InB, class InC,
1003         class OutA, class OutB, class OutC>
1004inline 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
1015template<class ObjT, class Method, class InA, class InB, class InC, class InD,
1016         class OutA, class OutB, class OutC>
1017inline 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
1029template<class ObjT, class Method,
1030         class InA, class InB, class InC, class InD, class InE,
1031         class OutA, class OutB, class OutC>
1032inline 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
1045template<class ObjT, class Method,
1046         class InA, class InB, class InC, class InD, class InE, class InF,
1047         class OutA, class OutB, class OutC>
1048inline 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
1064template<class ObjT, class Method,
1065         class OutA, class OutB, class OutC, class OutD>
1066inline 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
1072template<class ObjT, class Method, class InA,
1073         class OutA, class OutB, class OutC, class OutD>
1074inline 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
1084template<class ObjT, class Method, class InA,
1085         class OutA, class OutB, class OutC, class OutD>
1086inline 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
1096template<class ObjT, class Method, class InA, class InB,
1097         class OutA, class OutB, class OutC, class OutD>
1098inline 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
1109template<class ObjT, class Method, class InA, class InB, class InC,
1110         class OutA, class OutB, class OutC, class OutD>
1111inline 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
1123template<class ObjT, class Method, class InA, class InB, class InC, class InD,
1124         class OutA, class OutB, class OutC, class OutD>
1125inline 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
1138template<class ObjT, class Method,
1139         class InA, class InB, class InC, class InD, class InE,
1140         class OutA, class OutB, class OutC, class OutD>
1141inline 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
1155template<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>
1158inline 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
1175template<class ObjT, class Method,
1176         class OutA, class OutB, class OutC, class OutD, class OutE>
1177inline 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
1183template<class ObjT, class Method, class InA,
1184         class OutA, class OutB, class OutC, class OutD, class OutE>
1185inline 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
1196template<class ObjT, class Method, class InA,
1197         class OutA, class OutB, class OutC, class OutD, class OutE>
1198inline 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
1209template<class ObjT, class Method, class InA, class InB,
1210         class OutA, class OutB, class OutC, class OutD, class OutE>
1211inline 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
1223template<class ObjT, class Method, class InA, class InB, class InC,
1224         class OutA, class OutB, class OutC, class OutD, class OutE>
1225inline 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
1238template<class ObjT, class Method, class InA, class InB, class InC, class InD,
1239         class OutA, class OutB, class OutC, class OutD, class OutE>
1240inline 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
1254template<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>
1257inline 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
1272template<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>
1275inline 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