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