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 #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 
     45 template <class P>
     46 struct TupleTraits {
     47   typedef P ValueType;
     48   typedef P& RefType;
     49   typedef const P& ParamType;
     50 };
     51 
     52 template <class P>
     53 struct TupleTraits<P&> {
     54   typedef P ValueType;
     55   typedef P& RefType;
     56   typedef P& ParamType;
     57 };
     58 
     59 template <class P>
     60 struct 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 
     76 struct Tuple0 {
     77   typedef Tuple0 ValueTuple;
     78   typedef Tuple0 RefTuple;
     79   typedef Tuple0 ParamTuple;
     80 };
     81 
     82 template <class A>
     83 struct 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 
     93 template <class A, class B>
     94 struct 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 
    109 template <class A, class B, class C>
    110 struct 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 
    128 template <class A, class B, class C, class D>
    129 struct 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 
    150 template <class A, class B, class C, class D, class E>
    151 struct 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 
    175 template <class A, class B, class C, class D, class E, class F>
    176 struct 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 
    203 template <class A, class B, class C, class D, class E, class F, class G>
    204 struct 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 
    234 template <class A, class B, class C, class D, class E, class F, class G,
    235           class H>
    236 struct 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 
    274 template <>
    275 struct TupleTypes< Tuple0 > {
    276   typedef Tuple0 ValueTuple;
    277   typedef Tuple0 RefTuple;
    278   typedef Tuple0 ParamTuple;
    279 };
    280 
    281 template <class A>
    282 struct 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 
    288 template <class A, class B>
    289 struct TupleTypes< Tuple2<A, B> > {
    290   typedef Tuple2<typename TupleTraits<A>::ValueType,
    291                  typename TupleTraits<B>::ValueType> ValueTuple;
    292 typedef 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 
    298 template <class A, class B, class C>
    299 struct TupleTypes< Tuple3<A, B, C> > {
    300   typedef Tuple3<typename TupleTraits<A>::ValueType,
    301                  typename TupleTraits<B>::ValueType,
    302                  typename TupleTraits<C>::ValueType> ValueTuple;
    303 typedef 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 
    311 template <class A, class B, class C, class D>
    312 struct 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;
    317 typedef 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 
    327 template <class A, class B, class C, class D, class E>
    328 struct 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;
    334 typedef 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 
    346 template <class A, class B, class C, class D, class E, class F>
    347 struct 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;
    354 typedef 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 
    368 template <class A, class B, class C, class D, class E, class F, class G>
    369 struct 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;
    377 typedef 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 
    393 template <class A, class B, class C, class D, class E, class F, class G,
    394           class H>
    395 struct 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;
    404 typedef 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 
    427 inline Tuple0 MakeTuple() {
    428   return Tuple0();
    429 }
    430 
    431 template <class A>
    432 inline Tuple1<A> MakeTuple(const A& a) {
    433   return Tuple1<A>(a);
    434 }
    435 
    436 template <class A, class B>
    437 inline Tuple2<A, B> MakeTuple(const A& a, const B& b) {
    438   return Tuple2<A, B>(a, b);
    439 }
    440 
    441 template <class A, class B, class C>
    442 inline 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 
    446 template <class A, class B, class C, class D>
    447 inline 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 
    452 template <class A, class B, class C, class D, class E>
    453 inline 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 
    458 template <class A, class B, class C, class D, class E, class F>
    459 inline 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 
    464 template <class A, class B, class C, class D, class E, class F, class G>
    465 inline 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 
    471 template <class A, class B, class C, class D, class E, class F, class G,
    472           class H>
    473 inline 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 
    483 template <class A>
    484 inline Tuple1<A&> MakeRefTuple(A& a) {
    485   return Tuple1<A&>(a);
    486 }
    487 
    488 template <class A, class B>
    489 inline Tuple2<A&, B&> MakeRefTuple(A& a, B& b) {
    490   return Tuple2<A&, B&>(a, b);
    491 }
    492 
    493 template <class A, class B, class C>
    494 inline Tuple3<A&, B&, C&> MakeRefTuple(A& a, B& b, C& c) {
    495   return Tuple3<A&, B&, C&>(a, b, c);
    496 }
    497 
    498 template <class A, class B, class C, class D>
    499 inline 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 
    503 template <class A, class B, class C, class D, class E>
    504 inline 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 
    508 template <class A, class B, class C, class D, class E, class F>
    509 inline 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 
    514 template <class A, class B, class C, class D, class E, class F, class G>
    515 inline 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 
    520 template <class A, class B, class C, class D, class E, class F, class G,
    521           class H>
    522 inline 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 
    539 template <class ObjT, class Method>
    540 inline void DispatchToMethod(ObjT* obj, Method method, const Tuple0& arg) {
    541   (obj->*method)();
    542 }
    543 
    544 template <class ObjT, class Method, class A>
    545 inline void DispatchToMethod(ObjT* obj, Method method, const A& arg) {
    546   (obj->*method)(arg);
    547 }
    548 
    549 template <class ObjT, class Method, class A>
    550 inline void DispatchToMethod(ObjT* obj, Method method, const Tuple1<A>& arg) {
    551   (obj->*method)(arg.a);
    552 }
    553 
    554 template<class ObjT, class Method, class A, class B>
    555 inline void DispatchToMethod(ObjT* obj,
    556                              Method method,
    557                              const Tuple2<A, B>& arg) {
    558   (obj->*method)(arg.a, arg.b);
    559 }
    560 
    561 template<class ObjT, class Method, class A, class B, class C>
    562 inline void DispatchToMethod(ObjT* obj, Method method,
    563                              const Tuple3<A, B, C>& arg) {
    564   (obj->*method)(arg.a, arg.b, arg.c);
    565 }
    566 
    567 template<class ObjT, class Method, class A, class B, class C, class D>
    568 inline void DispatchToMethod(ObjT* obj, Method method,
    569                              const Tuple4<A, B, C, D>& arg) {
    570   (obj->*method)(arg.a, arg.b, arg.c, arg.d);
    571 }
    572 
    573 template<class ObjT, class Method, class A, class B, class C, class D, class E>
    574 inline 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 
    579 template<class ObjT, class Method, class A, class B, class C, class D, class E,
    580          class F>
    581 inline 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 
    586 template<class ObjT, class Method, class A, class B, class C, class D, class E,
    587          class F, class G>
    588 inline 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 
    593 template<class ObjT, class Method, class A, class B, class C, class D, class E,
    594          class F, class G, class H>
    595 inline 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 
    602 template <class Function>
    603 inline void DispatchToFunction(Function function, const Tuple0& arg) {
    604   (*function)();
    605 }
    606 
    607 template <class Function, class A>
    608 inline void DispatchToFunction(Function function, const A& arg) {
    609   (*function)(arg);
    610 }
    611 
    612 template <class Function, class A>
    613 inline void DispatchToFunction(Function function, const Tuple1<A>& arg) {
    614   (*function)(arg.a);
    615 }
    616 
    617 template<class Function, class A, class B>
    618 inline void DispatchToFunction(Function function, const Tuple2<A, B>& arg) {
    619   (*function)(arg.a, arg.b);
    620 }
    621 
    622 template<class Function, class A, class B, class C>
    623 inline void DispatchToFunction(Function function, const Tuple3<A, B, C>& arg) {
    624   (*function)(arg.a, arg.b, arg.c);
    625 }
    626 
    627 template<class Function, class A, class B, class C, class D>
    628 inline void DispatchToFunction(Function function,
    629                                const Tuple4<A, B, C, D>& arg) {
    630   (*function)(arg.a, arg.b, arg.c, arg.d);
    631 }
    632 
    633 template<class Function, class A, class B, class C, class D, class E>
    634 inline 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 
    639 template<class Function, class A, class B, class C, class D, class E, class F>
    640 inline 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 
    645 template<class Function, class A, class B, class C, class D, class E, class F,
    646          class G>
    647 inline 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 
    652 template<class Function, class A, class B, class C, class D, class E, class F,
    653          class G, class H>
    654 inline 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 
    661 template <class ObjT, class Method>
    662 inline void DispatchToMethod(ObjT* obj,
    663                              Method method,
    664                              const Tuple0& arg, Tuple0*) {
    665   (obj->*method)();
    666 }
    667 
    668 template <class ObjT, class Method, class A>
    669 inline void DispatchToMethod(ObjT* obj, Method method, const A& arg, Tuple0*) {
    670   (obj->*method)(arg);
    671 }
    672 
    673 template <class ObjT, class Method, class A>
    674 inline void DispatchToMethod(ObjT* obj,
    675                              Method method,
    676                              const Tuple1<A>& arg, Tuple0*) {
    677   (obj->*method)(arg.a);
    678 }
    679 
    680 template<class ObjT, class Method, class A, class B>
    681 inline void DispatchToMethod(ObjT* obj,
    682                              Method method,
    683                              const Tuple2<A, B>& arg, Tuple0*) {
    684   (obj->*method)(arg.a, arg.b);
    685 }
    686 
    687 template<class ObjT, class Method, class A, class B, class C>
    688 inline 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 
    693 template<class ObjT, class Method, class A, class B, class C, class D>
    694 inline 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 
    699 template<class ObjT, class Method, class A, class B, class C, class D, class E>
    700 inline 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 
    705 template<class ObjT, class Method, class A, class B, class C, class D, class E,
    706          class F>
    707 inline 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 
    714 template<class ObjT, class Method,
    715          class OutA>
    716 inline void DispatchToMethod(ObjT* obj, Method method,
    717                              const Tuple0& in,
    718                              Tuple1<OutA>* out) {
    719   (obj->*method)(&out->a);
    720 }
    721 
    722 template<class ObjT, class Method, class InA,
    723          class OutA>
    724 inline void DispatchToMethod(ObjT* obj, Method method,
    725                              const InA& in,
    726                              Tuple1<OutA>* out) {
    727   (obj->*method)(in, &out->a);
    728 }
    729 
    730 template<class ObjT, class Method, class InA,
    731          class OutA>
    732 inline void DispatchToMethod(ObjT* obj, Method method,
    733                              const Tuple1<InA>& in,
    734                              Tuple1<OutA>* out) {
    735   (obj->*method)(in.a, &out->a);
    736 }
    737 
    738 template<class ObjT, class Method, class InA, class InB,
    739          class OutA>
    740 inline 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 
    746 template<class ObjT, class Method, class InA, class InB, class InC,
    747          class OutA>
    748 inline 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 
    754 template<class ObjT, class Method, class InA, class InB, class InC, class InD,
    755          class OutA>
    756 inline 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 
    762 template<class ObjT, class Method, class InA, class InB, class InC, class InD,
    763          class InE, class OutA>
    764 inline 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 
    770 template<class ObjT, class Method,
    771          class InA, class InB, class InC, class InD, class InE, class InF,
    772          class OutA>
    773 inline 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 
    781 template<class ObjT, class Method,
    782          class OutA, class OutB>
    783 inline void DispatchToMethod(ObjT* obj, Method method,
    784                              const Tuple0& in,
    785                              Tuple2<OutA, OutB>* out) {
    786   (obj->*method)(&out->a, &out->b);
    787 }
    788 
    789 template<class ObjT, class Method, class InA,
    790          class OutA, class OutB>
    791 inline 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 
    797 template<class ObjT, class Method, class InA,
    798          class OutA, class OutB>
    799 inline 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 
    805 template<class ObjT, class Method, class InA, class InB,
    806          class OutA, class OutB>
    807 inline 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 
    813 template<class ObjT, class Method, class InA, class InB, class InC,
    814          class OutA, class OutB>
    815 inline 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 
    821 template<class ObjT, class Method, class InA, class InB, class InC, class InD,
    822          class OutA, class OutB>
    823 inline 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 
    829 template<class ObjT, class Method,
    830          class InA, class InB, class InC, class InD, class InE,
    831          class OutA, class OutB>
    832 inline 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 
    838 template<class ObjT, class Method,
    839          class InA, class InB, class InC, class InD, class InE, class InF,
    840          class OutA, class OutB>
    841 inline 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 
    849 template<class ObjT, class Method,
    850          class OutA, class OutB, class OutC>
    851 inline 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 
    857 template<class ObjT, class Method, class InA,
    858          class OutA, class OutB, class OutC>
    859 inline 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 
    865 template<class ObjT, class Method, class InA,
    866          class OutA, class OutB, class OutC>
    867 inline 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 
    873 template<class ObjT, class Method, class InA, class InB,
    874          class OutA, class OutB, class OutC>
    875 inline 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 
    881 template<class ObjT, class Method, class InA, class InB, class InC,
    882          class OutA, class OutB, class OutC>
    883 inline 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 
    889 template<class ObjT, class Method, class InA, class InB, class InC, class InD,
    890          class OutA, class OutB, class OutC>
    891 inline 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 
    897 template<class ObjT, class Method,
    898          class InA, class InB, class InC, class InD, class InE,
    899          class OutA, class OutB, class OutC>
    900 inline 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 
    906 template<class ObjT, class Method,
    907          class InA, class InB, class InC, class InD, class InE, class InF,
    908          class OutA, class OutB, class OutC>
    909 inline 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 
    917 template<class ObjT, class Method,
    918          class OutA, class OutB, class OutC, class OutD>
    919 inline 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 
    925 template<class ObjT, class Method, class InA,
    926          class OutA, class OutB, class OutC, class OutD>
    927 inline 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 
    933 template<class ObjT, class Method, class InA,
    934          class OutA, class OutB, class OutC, class OutD>
    935 inline 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 
    941 template<class ObjT, class Method, class InA, class InB,
    942          class OutA, class OutB, class OutC, class OutD>
    943 inline 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 
    949 template<class ObjT, class Method, class InA, class InB, class InC,
    950          class OutA, class OutB, class OutC, class OutD>
    951 inline 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 
    957 template<class ObjT, class Method, class InA, class InB, class InC, class InD,
    958          class OutA, class OutB, class OutC, class OutD>
    959 inline 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 
    965 template<class ObjT, class Method,
    966          class InA, class InB, class InC, class InD, class InE,
    967          class OutA, class OutB, class OutC, class OutD>
    968 inline 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 
    975 template<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>
    978 inline 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 
    987 template<class ObjT, class Method,
    988          class OutA, class OutB, class OutC, class OutD, class OutE>
    989 inline 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 
    995 template<class ObjT, class Method, class InA,
    996          class OutA, class OutB, class OutC, class OutD, class OutE>
    997 inline 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 
   1003 template<class ObjT, class Method, class InA,
   1004          class OutA, class OutB, class OutC, class OutD, class OutE>
   1005 inline 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 
   1011 template<class ObjT, class Method, class InA, class InB,
   1012          class OutA, class OutB, class OutC, class OutD, class OutE>
   1013 inline 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 
   1019 template<class ObjT, class Method, class InA, class InB, class InC,
   1020          class OutA, class OutB, class OutC, class OutD, class OutE>
   1021 inline 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 
   1027 template<class ObjT, class Method, class InA, class InB, class InC, class InD,
   1028          class OutA, class OutB, class OutC, class OutD, class OutE>
   1029 inline 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 
   1036 template<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>
   1039 inline 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 
   1046 template<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>
   1049 inline 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