blob: 6b0d336219b9e1cf40d5d042de7d69993b986fd3 [file] [log] [blame]
license.botf003cfe2008-08-24 09:55:55 +09001// 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.
initial.commit3f4a7322008-07-27 06:49:38 +09004
deanm@google.com96aac0a2008-08-25 22:42:07 +09005// A Tuple is a generic templatized container, similar in concept to std::pair.
ojan@google.com38355092008-10-10 06:58:05 +09006// There are classes Tuple0 to Tuple6, cooresponding to the number of elements
7// it contains. The convenient MakeTuple() function takes 0 to 6 arguments,
deanm@google.com96aac0a2008-08-25 22:42:07 +09008// 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
initial.commit3f4a7322008-07-27 06:49:38 +090029#ifndef BASE_TUPLE_H__
30#define BASE_TUPLE_H__
thakis@chromium.org01d14522010-07-27 08:08:24 +090031#pragma once
initial.commit3f4a7322008-07-27 06:49:38 +090032
oshima@chromium.org061e50f2010-12-02 09:11:40 +090033#if defined(OS_CHROMEOS)
34// To troubleshoot crosbug.com/7327.
35#include "base/logging.h"
36#endif
initial.commit3f4a7322008-07-27 06:49:38 +090037// 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
erg@google.come6ffcb52010-08-18 03:38:24 +090059template <class P>
60struct TupleTypes { };
61
initial.commit3f4a7322008-07-27 06:49:38 +090062// 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//
deanm@google.comff4b7292008-08-21 19:58:08 +090069// 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).
initial.commit3f4a7322008-07-27 06:49:38 +090072// 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;
mpcomplete@google.coma74ef822009-05-21 03:24:14 +090079 typedef Tuple0 ParamTuple;
initial.commit3f4a7322008-07-27 06:49:38 +090080};
81
82template <class A>
83struct Tuple1 {
84 public:
85 typedef A TypeA;
initial.commit3f4a7322008-07-27 06:49:38 +090086
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;
initial.commit3f4a7322008-07-27 06:49:38 +090098
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;
initial.commit3f4a7322008-07-27 06:49:38 +0900115
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;
initial.commit3f4a7322008-07-27 06:49:38 +0900135
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 {
erg@google.combf6ce9f2010-01-27 08:08:02 +0900152 public:
initial.commit3f4a7322008-07-27 06:49:38 +0900153 typedef A TypeA;
154 typedef B TypeB;
155 typedef C TypeC;
156 typedef D TypeD;
157 typedef E TypeE;
initial.commit3f4a7322008-07-27 06:49:38 +0900158
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
ojan@google.com38355092008-10-10 06:58:05 +0900175template <class A, class B, class C, class D, class E, class F>
176struct Tuple6 {
erg@google.combf6ce9f2010-01-27 08:08:02 +0900177 public:
ojan@google.com38355092008-10-10 06:58:05 +0900178 typedef A TypeA;
179 typedef B TypeB;
180 typedef C TypeC;
181 typedef D TypeD;
182 typedef E TypeE;
183 typedef F TypeF;
ojan@google.com38355092008-10-10 06:58:05 +0900184
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
sky@google.com67c35752008-11-13 07:10:20 +0900203template <class A, class B, class C, class D, class E, class F, class G>
204struct Tuple7 {
erg@google.combf6ce9f2010-01-27 08:08:02 +0900205 public:
sky@google.com67c35752008-11-13 07:10:20 +0900206 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;
sky@google.com67c35752008-11-13 07:10:20 +0900213
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
phajdan.jr@chromium.org5a468fc2010-07-21 01:56:26 +0900234template <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;
phajdan.jr@chromium.org5a468fc2010-07-21 01:56:26 +0900246
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
erg@google.come6ffcb52010-08-18 03:38:24 +0900269// 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
initial.commit3f4a7322008-07-27 06:49:38 +0900422// 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
ojan@google.com38355092008-10-10 06:58:05 +0900458template <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
sky@google.com67c35752008-11-13 07:10:20 +0900464template <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
phajdan.jr@chromium.org5a468fc2010-07-21 01:56:26 +0900471template <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
initial.commit3f4a7322008-07-27 06:49:38 +0900480// 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
ojan@google.com38355092008-10-10 06:58:05 +0900508template <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
sky@google.com67c35752008-11-13 07:10:20 +0900514template <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
phajdan.jr@chromium.org5a468fc2010-07-21 01:56:26 +0900520template <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
initial.commit3f4a7322008-07-27 06:49:38 +0900528// 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) {
oshima@chromium.orgb7c8e322010-11-11 08:47:56 +0900551
oshima@chromium.org061e50f2010-12-02 09:11:40 +0900552#if defined(OS_CHROMEOS)
oshima@chromium.orgb7c8e322010-11-11 08:47:56 +0900553 // To troubleshoot crosbug.com/7327.
554 CHECK(obj);
555 CHECK(&arg);
556 CHECK(method);
557#endif
initial.commit3f4a7322008-07-27 06:49:38 +0900558 (obj->*method)(arg.a);
559}
560
561template<class ObjT, class Method, class A, class B>
maruel@chromium.org8fe7adc2009-03-04 00:01:12 +0900562inline void DispatchToMethod(ObjT* obj,
563 Method method,
564 const Tuple2<A, B>& arg) {
initial.commit3f4a7322008-07-27 06:49:38 +0900565 (obj->*method)(arg.a, arg.b);
566}
567
568template<class ObjT, class Method, class A, class B, class C>
569inline void DispatchToMethod(ObjT* obj, Method method,
570 const Tuple3<A, B, C>& arg) {
571 (obj->*method)(arg.a, arg.b, arg.c);
572}
573
574template<class ObjT, class Method, class A, class B, class C, class D>
575inline void DispatchToMethod(ObjT* obj, Method method,
576 const Tuple4<A, B, C, D>& arg) {
577 (obj->*method)(arg.a, arg.b, arg.c, arg.d);
578}
579
580template<class ObjT, class Method, class A, class B, class C, class D, class E>
581inline void DispatchToMethod(ObjT* obj, Method method,
582 const Tuple5<A, B, C, D, E>& arg) {
583 (obj->*method)(arg.a, arg.b, arg.c, arg.d, arg.e);
584}
585
ojan@google.com38355092008-10-10 06:58:05 +0900586template<class ObjT, class Method, class A, class B, class C, class D, class E,
587 class F>
588inline void DispatchToMethod(ObjT* obj, Method method,
589 const Tuple6<A, B, C, D, E, F>& arg) {
590 (obj->*method)(arg.a, arg.b, arg.c, arg.d, arg.e, arg.f);
591}
592
sky@google.com67c35752008-11-13 07:10:20 +0900593template<class ObjT, class Method, class A, class B, class C, class D, class E,
594 class F, class G>
595inline void DispatchToMethod(ObjT* obj, Method method,
596 const Tuple7<A, B, C, D, E, F, G>& arg) {
597 (obj->*method)(arg.a, arg.b, arg.c, arg.d, arg.e, arg.f, arg.g);
598}
599
initial.commit3f4a7322008-07-27 06:49:38 +0900600// 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
ojan@google.com38355092008-10-10 06:58:05 +0900639template<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
phajdan.jr@chromium.org5a468fc2010-07-21 01:56:26 +0900645template<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
initial.commit3f4a7322008-07-27 06:49:38 +0900659// Dispatchers with 0 out param (as a Tuple0).
660
661template <class ObjT, class Method>
maruel@chromium.org8fe7adc2009-03-04 00:01:12 +0900662inline void DispatchToMethod(ObjT* obj,
663 Method method,
664 const Tuple0& arg, Tuple0*) {
initial.commit3f4a7322008-07-27 06:49:38 +0900665 (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>
maruel@chromium.org8fe7adc2009-03-04 00:01:12 +0900674inline void DispatchToMethod(ObjT* obj,
675 Method method,
676 const Tuple1<A>& arg, Tuple0*) {
initial.commit3f4a7322008-07-27 06:49:38 +0900677 (obj->*method)(arg.a);
678}
679
680template<class ObjT, class Method, class A, class B>
maruel@chromium.org8fe7adc2009-03-04 00:01:12 +0900681inline void DispatchToMethod(ObjT* obj,
682 Method method,
683 const Tuple2<A, B>& arg, Tuple0*) {
initial.commit3f4a7322008-07-27 06:49:38 +0900684 (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
ojan@google.com38355092008-10-10 06:58:05 +0900705template<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
initial.commit3f4a7322008-07-27 06:49:38 +0900712// 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
erg@google.combf6ce9f2010-01-27 08:08:02 +0900762template<class ObjT, class Method, class InA, class InB, class InC, class InD,
763 class InE, class OutA>
initial.commit3f4a7322008-07-27 06:49:38 +0900764inline 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
ojan@google.com38355092008-10-10 06:58:05 +0900770template<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
initial.commit3f4a7322008-07-27 06:49:38 +0900779// 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
ojan@google.com38355092008-10-10 06:58:05 +0900838template<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
initial.commit3f4a7322008-07-27 06:49:38 +0900847// 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
ojan@google.com38355092008-10-10 06:58:05 +0900906template<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
initial.commit3f4a7322008-07-27 06:49:38 +0900915// 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
ojan@google.com38355092008-10-10 06:58:05 +0900975template<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
initial.commit3f4a7322008-07-27 06:49:38 +0900985// 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
ojan@google.com38355092008-10-10 06:58:05 +09001046template<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
initial.commit3f4a7322008-07-27 06:49:38 +09001056#endif // BASE_TUPLE_H__