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