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