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