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