tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

tuple.h (31197B)


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