blob: fe3764bfb5145c5da73fb5d68fb99108335f8f2e [file] [log] [blame]
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001// This file was GENERATED by command:
2// pump.py bind_internal.h.pump
3// DO NOT EDIT BY HAND!!!
4
5
6// Copyright (c) 2011 The Chromium Authors. All rights reserved.
7// Use of this source code is governed by a BSD-style license that can be
8// found in the LICENSE file.
9
10#ifndef BASE_BIND_INTERNAL_H_
11#define BASE_BIND_INTERNAL_H_
12#pragma once
13
14#include "base/bind_helpers.h"
ajwong@chromium.orgfa0ff432011-02-19 08:29:31 +090015#include "base/callback_internal.h"
ajwong@chromium.orge2cca632011-02-15 10:27:38 +090016#include "base/template_util.h"
17
18namespace base {
19namespace internal {
20
21// The method by which a function is invoked is determined by 3 different
22// dimensions:
23//
ajwong@chromium.orge0648232011-02-19 09:52:15 +090024// 1) The type of function (normal or method).
25// 2) The arity of the function.
ajwong@chromium.orge2cca632011-02-15 10:27:38 +090026// 3) The number of bound parameters.
27//
ajwong@chromium.orge0648232011-02-19 09:52:15 +090028// The templates below handle the determination of each of these dimensions.
29// In brief:
ajwong@chromium.orge2cca632011-02-15 10:27:38 +090030//
ajwong@chromium.orge0648232011-02-19 09:52:15 +090031// FunctionTraits<> -- Provides a normalied signature, and other traits.
32// InvokerN<> -- Provides a DoInvoke() function that actually executes
33// a calback.
34// InvokerStorageN<> -- Provides storage for the bound parameters, and
35// typedefs to the above.
36//
37// More details about the design of each class is included in a comment closer
38// to their defition.
39
40// FunctionTraits<>
41//
42// The FunctionTraits<> template determines the type of function, and also
43// creates a NormalizedType used to select the InvokerN classes. It turns out
44// that syntactically, you only really have 2 variations when invoking a
45// funciton pointer: normal, and method. One is invoked func_ptr(arg1). The
46// other is invoked (*obj_->method_ptr(arg1)).
47//
48// However, in the type system, there are many more distinctions. In standard
49// C++, there's all variations of const, and volatile on the function pointer.
50// In Windows, there are additional calling conventions (eg., __stdcall,
51// __fastcall, etc.). FunctionTraits<> handles categorizing each of these into
52// a normalized signature.
53//
54// Having a NormalizedSignature signature, reduces the combinatoric
55// complexity of defintions for the InvokerN<> later. Even though there are
56// only 2 syntactic variations on invoking a function, without normalizing the
57// signature, there would need to be one specialization of InvokerN for each
58// unique (function_type, bound_arg, unbound_args) tuple in order to match all
59// function signatures.
60//
61// By normalizing the function signature, we reduce function_type to exactly 2.
62
63template <typename Sig>
64struct FunctionTraits;
65
66// Function: Arity 0.
67template <typename R>
68struct FunctionTraits<R(*)()> {
69 typedef R (*NormalizedSig)();
70 typedef base::false_type IsMethod;
71};
72
73// Method: Arity 0.
74template <typename R, typename T>
75struct FunctionTraits<R(T::*)()> {
76 typedef R (T::*NormalizedSig)();
77 typedef base::true_type IsMethod;
78};
79
80// Const Method: Arity 0.
81template <typename R, typename T>
82struct FunctionTraits<R(T::*)() const> {
83 typedef R (T::*NormalizedSig)();
84 typedef base::true_type IsMethod;
85};
86
87// Function: Arity 1.
88template <typename R, typename X1>
89struct FunctionTraits<R(*)(X1)> {
90 typedef R (*NormalizedSig)(X1);
91 typedef base::false_type IsMethod;
92};
93
94// Method: Arity 1.
95template <typename R, typename T, typename X1>
96struct FunctionTraits<R(T::*)(X1)> {
97 typedef R (T::*NormalizedSig)(X1);
98 typedef base::true_type IsMethod;
99};
100
101// Const Method: Arity 1.
102template <typename R, typename T, typename X1>
103struct FunctionTraits<R(T::*)(X1) const> {
104 typedef R (T::*NormalizedSig)(X1);
105 typedef base::true_type IsMethod;
106};
107
108// Function: Arity 2.
109template <typename R, typename X1, typename X2>
110struct FunctionTraits<R(*)(X1, X2)> {
111 typedef R (*NormalizedSig)(X1, X2);
112 typedef base::false_type IsMethod;
113};
114
115// Method: Arity 2.
116template <typename R, typename T, typename X1, typename X2>
117struct FunctionTraits<R(T::*)(X1, X2)> {
118 typedef R (T::*NormalizedSig)(X1, X2);
119 typedef base::true_type IsMethod;
120};
121
122// Const Method: Arity 2.
123template <typename R, typename T, typename X1, typename X2>
124struct FunctionTraits<R(T::*)(X1, X2) const> {
125 typedef R (T::*NormalizedSig)(X1, X2);
126 typedef base::true_type IsMethod;
127};
128
129// Function: Arity 3.
130template <typename R, typename X1, typename X2, typename X3>
131struct FunctionTraits<R(*)(X1, X2, X3)> {
132 typedef R (*NormalizedSig)(X1, X2, X3);
133 typedef base::false_type IsMethod;
134};
135
136// Method: Arity 3.
137template <typename R, typename T, typename X1, typename X2, typename X3>
138struct FunctionTraits<R(T::*)(X1, X2, X3)> {
139 typedef R (T::*NormalizedSig)(X1, X2, X3);
140 typedef base::true_type IsMethod;
141};
142
143// Const Method: Arity 3.
144template <typename R, typename T, typename X1, typename X2, typename X3>
145struct FunctionTraits<R(T::*)(X1, X2, X3) const> {
146 typedef R (T::*NormalizedSig)(X1, X2, X3);
147 typedef base::true_type IsMethod;
148};
149
150// Function: Arity 4.
151template <typename R, typename X1, typename X2, typename X3, typename X4>
152struct FunctionTraits<R(*)(X1, X2, X3, X4)> {
153 typedef R (*NormalizedSig)(X1, X2, X3, X4);
154 typedef base::false_type IsMethod;
155};
156
157// Method: Arity 4.
158template <typename R, typename T, typename X1, typename X2, typename X3,
159 typename X4>
160struct FunctionTraits<R(T::*)(X1, X2, X3, X4)> {
161 typedef R (T::*NormalizedSig)(X1, X2, X3, X4);
162 typedef base::true_type IsMethod;
163};
164
165// Const Method: Arity 4.
166template <typename R, typename T, typename X1, typename X2, typename X3,
167 typename X4>
168struct FunctionTraits<R(T::*)(X1, X2, X3, X4) const> {
169 typedef R (T::*NormalizedSig)(X1, X2, X3, X4);
170 typedef base::true_type IsMethod;
171};
172
173// Function: Arity 5.
174template <typename R, typename X1, typename X2, typename X3, typename X4,
175 typename X5>
176struct FunctionTraits<R(*)(X1, X2, X3, X4, X5)> {
177 typedef R (*NormalizedSig)(X1, X2, X3, X4, X5);
178 typedef base::false_type IsMethod;
179};
180
181// Method: Arity 5.
182template <typename R, typename T, typename X1, typename X2, typename X3,
183 typename X4, typename X5>
184struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5)> {
185 typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5);
186 typedef base::true_type IsMethod;
187};
188
189// Const Method: Arity 5.
190template <typename R, typename T, typename X1, typename X2, typename X3,
191 typename X4, typename X5>
192struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5) const> {
193 typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5);
194 typedef base::true_type IsMethod;
195};
196
197// Function: Arity 6.
198template <typename R, typename X1, typename X2, typename X3, typename X4,
199 typename X5, typename X6>
200struct FunctionTraits<R(*)(X1, X2, X3, X4, X5, X6)> {
201 typedef R (*NormalizedSig)(X1, X2, X3, X4, X5, X6);
202 typedef base::false_type IsMethod;
203};
204
205// Method: Arity 6.
206template <typename R, typename T, typename X1, typename X2, typename X3,
207 typename X4, typename X5, typename X6>
208struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5, X6)> {
209 typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5, X6);
210 typedef base::true_type IsMethod;
211};
212
213// Const Method: Arity 6.
214template <typename R, typename T, typename X1, typename X2, typename X3,
215 typename X4, typename X5, typename X6>
216struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5, X6) const> {
217 typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5, X6);
218 typedef base::true_type IsMethod;
219};
220
221// InvokerN<>
222//
223// The InvokerN templates contain a static DoInvoke() function that is the key
224// to implementing type erasure in the Callback() classes.
225//
226// DoInvoke() is a static function with a fixed signature that is independent
227// of StorageType; its first argument is a pointer to the non-templated common
228// baseclass of StorageType. This lets us store pointer to DoInvoke() in a
229// function pointer that has knowledge of the specific StorageType, and thus
230// no knowledge of the bound function and bound parameter types.
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900231//
232// As long as we ensure that DoInvoke() is only used with pointers there were
233// upcasted from the correct StorageType, we can be sure that execution is
234// safe.
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900235//
236// The InvokerN templates are the only point that knows the number of bound
237// and unbound arguments. This is intentional because it allows the other
238// templates classes in the system to only have as many specializations as
239// the max arity of function we wish to support.
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900240
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900241template <typename StorageType, typename NormalizedSig>
242struct Invoker0;
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900243
244// Function: Arity 0 -> 0.
245template <typename StorageType, typename R>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900246struct Invoker0<StorageType, R(*)()> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900247 static R DoInvoke(InvokerStorageBase* base) {
248 StorageType* invoker = static_cast<StorageType*>(base);
249 return invoker->f_();
250 }
251};
252
253// Function: Arity 1 -> 1.
254template <typename StorageType, typename R,typename X1>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900255struct Invoker0<StorageType, R(*)(X1)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900256 COMPILE_ASSERT(
257 !( is_non_const_reference<X1>::value ),
258 do_not_bind_functions_with_nonconst_ref);
259
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900260 static R DoInvoke(InvokerStorageBase* base, const X1& x1) {
261 StorageType* invoker = static_cast<StorageType*>(base);
262 return invoker->f_(x1);
263 }
264};
265
266// Function: Arity 2 -> 2.
267template <typename StorageType, typename R,typename X1, typename X2>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900268struct Invoker0<StorageType, R(*)(X1, X2)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900269 COMPILE_ASSERT(
270 !( is_non_const_reference<X1>::value ||
271 is_non_const_reference<X2>::value ),
272 do_not_bind_functions_with_nonconst_ref);
273
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900274 static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2) {
275 StorageType* invoker = static_cast<StorageType*>(base);
276 return invoker->f_(x1, x2);
277 }
278};
279
280// Function: Arity 3 -> 3.
281template <typename StorageType, typename R,typename X1, typename X2,
282 typename X3>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900283struct Invoker0<StorageType, R(*)(X1, X2, X3)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900284 COMPILE_ASSERT(
285 !( is_non_const_reference<X1>::value ||
286 is_non_const_reference<X2>::value ||
287 is_non_const_reference<X3>::value ),
288 do_not_bind_functions_with_nonconst_ref);
289
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900290 static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
291 const X3& x3) {
292 StorageType* invoker = static_cast<StorageType*>(base);
293 return invoker->f_(x1, x2, x3);
294 }
295};
296
297// Function: Arity 4 -> 4.
298template <typename StorageType, typename R,typename X1, typename X2,
299 typename X3, typename X4>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900300struct Invoker0<StorageType, R(*)(X1, X2, X3, X4)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900301 COMPILE_ASSERT(
302 !( is_non_const_reference<X1>::value ||
303 is_non_const_reference<X2>::value ||
304 is_non_const_reference<X3>::value ||
305 is_non_const_reference<X4>::value ),
306 do_not_bind_functions_with_nonconst_ref);
307
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900308 static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
309 const X3& x3, const X4& x4) {
310 StorageType* invoker = static_cast<StorageType*>(base);
311 return invoker->f_(x1, x2, x3, x4);
312 }
313};
314
315// Function: Arity 5 -> 5.
316template <typename StorageType, typename R,typename X1, typename X2,
317 typename X3, typename X4, typename X5>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900318struct Invoker0<StorageType, R(*)(X1, X2, X3, X4, X5)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900319 COMPILE_ASSERT(
320 !( is_non_const_reference<X1>::value ||
321 is_non_const_reference<X2>::value ||
322 is_non_const_reference<X3>::value ||
323 is_non_const_reference<X4>::value ||
324 is_non_const_reference<X5>::value ),
325 do_not_bind_functions_with_nonconst_ref);
326
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900327 static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
328 const X3& x3, const X4& x4, const X5& x5) {
329 StorageType* invoker = static_cast<StorageType*>(base);
330 return invoker->f_(x1, x2, x3, x4, x5);
331 }
332};
333
334// Function: Arity 6 -> 6.
335template <typename StorageType, typename R,typename X1, typename X2,
336 typename X3, typename X4, typename X5, typename X6>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900337struct Invoker0<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900338 COMPILE_ASSERT(
339 !( is_non_const_reference<X1>::value ||
340 is_non_const_reference<X2>::value ||
341 is_non_const_reference<X3>::value ||
342 is_non_const_reference<X4>::value ||
343 is_non_const_reference<X5>::value ||
344 is_non_const_reference<X6>::value ),
345 do_not_bind_functions_with_nonconst_ref);
346
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900347 static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
348 const X3& x3, const X4& x4, const X5& x5, const X6& x6) {
349 StorageType* invoker = static_cast<StorageType*>(base);
350 return invoker->f_(x1, x2, x3, x4, x5, x6);
351 }
352};
353
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900354template <typename StorageType, typename NormalizedSig>
355struct Invoker1;
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900356
357// Function: Arity 1 -> 0.
358template <typename StorageType, typename R,typename X1>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900359struct Invoker1<StorageType, R(*)(X1)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900360 COMPILE_ASSERT(
361 !( is_non_const_reference<X1>::value ),
362 do_not_bind_functions_with_nonconst_ref);
363
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900364 static R DoInvoke(InvokerStorageBase* base) {
365 StorageType* invoker = static_cast<StorageType*>(base);
366 return invoker->f_(Unwrap(invoker->p1_));
367 }
368};
369
370// Method: Arity 0 -> 0.
371template <typename StorageType, typename R, typename T>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900372struct Invoker1<StorageType, R(T::*)()> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900373 static R DoInvoke(InvokerStorageBase* base) {
374 StorageType* invoker = static_cast<StorageType*>(base);
375 return (Unwrap(invoker->p1_)->*invoker->f_)();
376 }
377};
378
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900379// Function: Arity 2 -> 1.
380template <typename StorageType, typename R,typename X1, typename X2>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900381struct Invoker1<StorageType, R(*)(X1, X2)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900382 COMPILE_ASSERT(
383 !( is_non_const_reference<X1>::value ||
384 is_non_const_reference<X2>::value ),
385 do_not_bind_functions_with_nonconst_ref);
386
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900387 static R DoInvoke(InvokerStorageBase* base, const X2& x2) {
388 StorageType* invoker = static_cast<StorageType*>(base);
389 return invoker->f_(Unwrap(invoker->p1_), x2);
390 }
391};
392
393// Method: Arity 1 -> 1.
394template <typename StorageType, typename R, typename T, typename X1>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900395struct Invoker1<StorageType, R(T::*)(X1)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900396 COMPILE_ASSERT(
397 !( is_non_const_reference<X1>::value ),
398 do_not_bind_functions_with_nonconst_ref);
399
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900400 static R DoInvoke(InvokerStorageBase* base, const X1& x1) {
401 StorageType* invoker = static_cast<StorageType*>(base);
402 return (Unwrap(invoker->p1_)->*invoker->f_)(x1);
403 }
404};
405
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900406// Function: Arity 3 -> 2.
407template <typename StorageType, typename R,typename X1, typename X2,
408 typename X3>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900409struct Invoker1<StorageType, R(*)(X1, X2, X3)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900410 COMPILE_ASSERT(
411 !( is_non_const_reference<X1>::value ||
412 is_non_const_reference<X2>::value ||
413 is_non_const_reference<X3>::value ),
414 do_not_bind_functions_with_nonconst_ref);
415
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900416 static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3) {
417 StorageType* invoker = static_cast<StorageType*>(base);
418 return invoker->f_(Unwrap(invoker->p1_), x2, x3);
419 }
420};
421
422// Method: Arity 2 -> 2.
423template <typename StorageType, typename R, typename T, typename X1,
424 typename X2>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900425struct Invoker1<StorageType, R(T::*)(X1, X2)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900426 COMPILE_ASSERT(
427 !( is_non_const_reference<X1>::value ||
428 is_non_const_reference<X2>::value ),
429 do_not_bind_functions_with_nonconst_ref);
430
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900431 static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2) {
432 StorageType* invoker = static_cast<StorageType*>(base);
433 return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2);
434 }
435};
436
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900437// Function: Arity 4 -> 3.
438template <typename StorageType, typename R,typename X1, typename X2,
439 typename X3, typename X4>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900440struct Invoker1<StorageType, R(*)(X1, X2, X3, X4)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900441 COMPILE_ASSERT(
442 !( is_non_const_reference<X1>::value ||
443 is_non_const_reference<X2>::value ||
444 is_non_const_reference<X3>::value ||
445 is_non_const_reference<X4>::value ),
446 do_not_bind_functions_with_nonconst_ref);
447
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900448 static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3,
449 const X4& x4) {
450 StorageType* invoker = static_cast<StorageType*>(base);
451 return invoker->f_(Unwrap(invoker->p1_), x2, x3, x4);
452 }
453};
454
455// Method: Arity 3 -> 3.
456template <typename StorageType, typename R, typename T, typename X1,
457 typename X2, typename X3>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900458struct Invoker1<StorageType, R(T::*)(X1, X2, X3)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900459 COMPILE_ASSERT(
460 !( is_non_const_reference<X1>::value ||
461 is_non_const_reference<X2>::value ||
462 is_non_const_reference<X3>::value ),
463 do_not_bind_functions_with_nonconst_ref);
464
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900465 static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
466 const X3& x3) {
467 StorageType* invoker = static_cast<StorageType*>(base);
468 return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2, x3);
469 }
470};
471
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900472// Function: Arity 5 -> 4.
473template <typename StorageType, typename R,typename X1, typename X2,
474 typename X3, typename X4, typename X5>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900475struct Invoker1<StorageType, R(*)(X1, X2, X3, X4, X5)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900476 COMPILE_ASSERT(
477 !( is_non_const_reference<X1>::value ||
478 is_non_const_reference<X2>::value ||
479 is_non_const_reference<X3>::value ||
480 is_non_const_reference<X4>::value ||
481 is_non_const_reference<X5>::value ),
482 do_not_bind_functions_with_nonconst_ref);
483
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900484 static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3,
485 const X4& x4, const X5& x5) {
486 StorageType* invoker = static_cast<StorageType*>(base);
487 return invoker->f_(Unwrap(invoker->p1_), x2, x3, x4, x5);
488 }
489};
490
491// Method: Arity 4 -> 4.
492template <typename StorageType, typename R, typename T, typename X1,
493 typename X2, typename X3, typename X4>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900494struct Invoker1<StorageType, R(T::*)(X1, X2, X3, X4)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900495 COMPILE_ASSERT(
496 !( is_non_const_reference<X1>::value ||
497 is_non_const_reference<X2>::value ||
498 is_non_const_reference<X3>::value ||
499 is_non_const_reference<X4>::value ),
500 do_not_bind_functions_with_nonconst_ref);
501
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900502 static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
503 const X3& x3, const X4& x4) {
504 StorageType* invoker = static_cast<StorageType*>(base);
505 return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2, x3, x4);
506 }
507};
508
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900509// Function: Arity 6 -> 5.
510template <typename StorageType, typename R,typename X1, typename X2,
511 typename X3, typename X4, typename X5, typename X6>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900512struct Invoker1<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900513 COMPILE_ASSERT(
514 !( is_non_const_reference<X1>::value ||
515 is_non_const_reference<X2>::value ||
516 is_non_const_reference<X3>::value ||
517 is_non_const_reference<X4>::value ||
518 is_non_const_reference<X5>::value ||
519 is_non_const_reference<X6>::value ),
520 do_not_bind_functions_with_nonconst_ref);
521
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900522 static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3,
523 const X4& x4, const X5& x5, const X6& x6) {
524 StorageType* invoker = static_cast<StorageType*>(base);
525 return invoker->f_(Unwrap(invoker->p1_), x2, x3, x4, x5, x6);
526 }
527};
528
529// Method: Arity 5 -> 5.
530template <typename StorageType, typename R, typename T, typename X1,
531 typename X2, typename X3, typename X4, typename X5>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900532struct Invoker1<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900533 COMPILE_ASSERT(
534 !( is_non_const_reference<X1>::value ||
535 is_non_const_reference<X2>::value ||
536 is_non_const_reference<X3>::value ||
537 is_non_const_reference<X4>::value ||
538 is_non_const_reference<X5>::value ),
539 do_not_bind_functions_with_nonconst_ref);
540
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900541 static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
542 const X3& x3, const X4& x4, const X5& x5) {
543 StorageType* invoker = static_cast<StorageType*>(base);
544 return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2, x3, x4, x5);
545 }
546};
547
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900548template <typename StorageType, typename NormalizedSig>
549struct Invoker2;
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900550
551// Function: Arity 2 -> 0.
552template <typename StorageType, typename R,typename X1, typename X2>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900553struct Invoker2<StorageType, R(*)(X1, X2)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900554 COMPILE_ASSERT(
555 !( is_non_const_reference<X1>::value ||
556 is_non_const_reference<X2>::value ),
557 do_not_bind_functions_with_nonconst_ref);
558
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900559 static R DoInvoke(InvokerStorageBase* base) {
560 StorageType* invoker = static_cast<StorageType*>(base);
561 return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_));
562 }
563};
564
565// Method: Arity 1 -> 0.
566template <typename StorageType, typename R, typename T, typename X1>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900567struct Invoker2<StorageType, R(T::*)(X1)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900568 COMPILE_ASSERT(
569 !( is_non_const_reference<X1>::value ),
570 do_not_bind_functions_with_nonconst_ref);
571
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900572 static R DoInvoke(InvokerStorageBase* base) {
573 StorageType* invoker = static_cast<StorageType*>(base);
574 return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_));
575 }
576};
577
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900578// Function: Arity 3 -> 1.
579template <typename StorageType, typename R,typename X1, typename X2,
580 typename X3>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900581struct Invoker2<StorageType, R(*)(X1, X2, X3)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900582 COMPILE_ASSERT(
583 !( is_non_const_reference<X1>::value ||
584 is_non_const_reference<X2>::value ||
585 is_non_const_reference<X3>::value ),
586 do_not_bind_functions_with_nonconst_ref);
587
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900588 static R DoInvoke(InvokerStorageBase* base, const X3& x3) {
589 StorageType* invoker = static_cast<StorageType*>(base);
590 return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3);
591 }
592};
593
594// Method: Arity 2 -> 1.
595template <typename StorageType, typename R, typename T, typename X1,
596 typename X2>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900597struct Invoker2<StorageType, R(T::*)(X1, X2)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900598 COMPILE_ASSERT(
599 !( is_non_const_reference<X1>::value ||
600 is_non_const_reference<X2>::value ),
601 do_not_bind_functions_with_nonconst_ref);
602
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900603 static R DoInvoke(InvokerStorageBase* base, const X2& x2) {
604 StorageType* invoker = static_cast<StorageType*>(base);
605 return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2);
606 }
607};
608
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900609// Function: Arity 4 -> 2.
610template <typename StorageType, typename R,typename X1, typename X2,
611 typename X3, typename X4>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900612struct Invoker2<StorageType, R(*)(X1, X2, X3, X4)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900613 COMPILE_ASSERT(
614 !( is_non_const_reference<X1>::value ||
615 is_non_const_reference<X2>::value ||
616 is_non_const_reference<X3>::value ||
617 is_non_const_reference<X4>::value ),
618 do_not_bind_functions_with_nonconst_ref);
619
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900620 static R DoInvoke(InvokerStorageBase* base, const X3& x3, const X4& x4) {
621 StorageType* invoker = static_cast<StorageType*>(base);
622 return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3, x4);
623 }
624};
625
626// Method: Arity 3 -> 2.
627template <typename StorageType, typename R, typename T, typename X1,
628 typename X2, typename X3>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900629struct Invoker2<StorageType, R(T::*)(X1, X2, X3)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900630 COMPILE_ASSERT(
631 !( is_non_const_reference<X1>::value ||
632 is_non_const_reference<X2>::value ||
633 is_non_const_reference<X3>::value ),
634 do_not_bind_functions_with_nonconst_ref);
635
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900636 static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3) {
637 StorageType* invoker = static_cast<StorageType*>(base);
638 return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2, x3);
639 }
640};
641
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900642// Function: Arity 5 -> 3.
643template <typename StorageType, typename R,typename X1, typename X2,
644 typename X3, typename X4, typename X5>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900645struct Invoker2<StorageType, R(*)(X1, X2, X3, X4, X5)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900646 COMPILE_ASSERT(
647 !( is_non_const_reference<X1>::value ||
648 is_non_const_reference<X2>::value ||
649 is_non_const_reference<X3>::value ||
650 is_non_const_reference<X4>::value ||
651 is_non_const_reference<X5>::value ),
652 do_not_bind_functions_with_nonconst_ref);
653
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900654 static R DoInvoke(InvokerStorageBase* base, const X3& x3, const X4& x4,
655 const X5& x5) {
656 StorageType* invoker = static_cast<StorageType*>(base);
657 return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3, x4, x5);
658 }
659};
660
661// Method: Arity 4 -> 3.
662template <typename StorageType, typename R, typename T, typename X1,
663 typename X2, typename X3, typename X4>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900664struct Invoker2<StorageType, R(T::*)(X1, X2, X3, X4)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900665 COMPILE_ASSERT(
666 !( is_non_const_reference<X1>::value ||
667 is_non_const_reference<X2>::value ||
668 is_non_const_reference<X3>::value ||
669 is_non_const_reference<X4>::value ),
670 do_not_bind_functions_with_nonconst_ref);
671
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900672 static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3,
673 const X4& x4) {
674 StorageType* invoker = static_cast<StorageType*>(base);
675 return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2, x3,
676 x4);
677 }
678};
679
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900680// Function: Arity 6 -> 4.
681template <typename StorageType, typename R,typename X1, typename X2,
682 typename X3, typename X4, typename X5, typename X6>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900683struct Invoker2<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900684 COMPILE_ASSERT(
685 !( is_non_const_reference<X1>::value ||
686 is_non_const_reference<X2>::value ||
687 is_non_const_reference<X3>::value ||
688 is_non_const_reference<X4>::value ||
689 is_non_const_reference<X5>::value ||
690 is_non_const_reference<X6>::value ),
691 do_not_bind_functions_with_nonconst_ref);
692
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900693 static R DoInvoke(InvokerStorageBase* base, const X3& x3, const X4& x4,
694 const X5& x5, const X6& x6) {
695 StorageType* invoker = static_cast<StorageType*>(base);
696 return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3, x4, x5,
697 x6);
698 }
699};
700
701// Method: Arity 5 -> 4.
702template <typename StorageType, typename R, typename T, typename X1,
703 typename X2, typename X3, typename X4, typename X5>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900704struct Invoker2<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900705 COMPILE_ASSERT(
706 !( is_non_const_reference<X1>::value ||
707 is_non_const_reference<X2>::value ||
708 is_non_const_reference<X3>::value ||
709 is_non_const_reference<X4>::value ||
710 is_non_const_reference<X5>::value ),
711 do_not_bind_functions_with_nonconst_ref);
712
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900713 static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3,
714 const X4& x4, const X5& x5) {
715 StorageType* invoker = static_cast<StorageType*>(base);
716 return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2, x3,
717 x4, x5);
718 }
719};
720
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900721template <typename StorageType, typename NormalizedSig>
722struct Invoker3;
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900723
724// Function: Arity 3 -> 0.
725template <typename StorageType, typename R,typename X1, typename X2,
726 typename X3>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900727struct Invoker3<StorageType, R(*)(X1, X2, X3)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900728 COMPILE_ASSERT(
729 !( is_non_const_reference<X1>::value ||
730 is_non_const_reference<X2>::value ||
731 is_non_const_reference<X3>::value ),
732 do_not_bind_functions_with_nonconst_ref);
733
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900734 static R DoInvoke(InvokerStorageBase* base) {
735 StorageType* invoker = static_cast<StorageType*>(base);
736 return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
737 Unwrap(invoker->p3_));
738 }
739};
740
741// Method: Arity 2 -> 0.
742template <typename StorageType, typename R, typename T, typename X1,
743 typename X2>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900744struct Invoker3<StorageType, R(T::*)(X1, X2)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900745 COMPILE_ASSERT(
746 !( is_non_const_reference<X1>::value ||
747 is_non_const_reference<X2>::value ),
748 do_not_bind_functions_with_nonconst_ref);
749
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900750 static R DoInvoke(InvokerStorageBase* base) {
751 StorageType* invoker = static_cast<StorageType*>(base);
752 return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
753 Unwrap(invoker->p3_));
754 }
755};
756
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900757// Function: Arity 4 -> 1.
758template <typename StorageType, typename R,typename X1, typename X2,
759 typename X3, typename X4>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900760struct Invoker3<StorageType, R(*)(X1, X2, X3, X4)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900761 COMPILE_ASSERT(
762 !( is_non_const_reference<X1>::value ||
763 is_non_const_reference<X2>::value ||
764 is_non_const_reference<X3>::value ||
765 is_non_const_reference<X4>::value ),
766 do_not_bind_functions_with_nonconst_ref);
767
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900768 static R DoInvoke(InvokerStorageBase* base, const X4& x4) {
769 StorageType* invoker = static_cast<StorageType*>(base);
770 return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
771 Unwrap(invoker->p3_), x4);
772 }
773};
774
775// Method: Arity 3 -> 1.
776template <typename StorageType, typename R, typename T, typename X1,
777 typename X2, typename X3>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900778struct Invoker3<StorageType, R(T::*)(X1, X2, X3)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900779 COMPILE_ASSERT(
780 !( is_non_const_reference<X1>::value ||
781 is_non_const_reference<X2>::value ||
782 is_non_const_reference<X3>::value ),
783 do_not_bind_functions_with_nonconst_ref);
784
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900785 static R DoInvoke(InvokerStorageBase* base, const X3& x3) {
786 StorageType* invoker = static_cast<StorageType*>(base);
787 return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
788 Unwrap(invoker->p3_), x3);
789 }
790};
791
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900792// Function: Arity 5 -> 2.
793template <typename StorageType, typename R,typename X1, typename X2,
794 typename X3, typename X4, typename X5>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900795struct Invoker3<StorageType, R(*)(X1, X2, X3, X4, X5)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900796 COMPILE_ASSERT(
797 !( is_non_const_reference<X1>::value ||
798 is_non_const_reference<X2>::value ||
799 is_non_const_reference<X3>::value ||
800 is_non_const_reference<X4>::value ||
801 is_non_const_reference<X5>::value ),
802 do_not_bind_functions_with_nonconst_ref);
803
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900804 static R DoInvoke(InvokerStorageBase* base, const X4& x4, const X5& x5) {
805 StorageType* invoker = static_cast<StorageType*>(base);
806 return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
807 Unwrap(invoker->p3_), x4, x5);
808 }
809};
810
811// Method: Arity 4 -> 2.
812template <typename StorageType, typename R, typename T, typename X1,
813 typename X2, typename X3, typename X4>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900814struct Invoker3<StorageType, R(T::*)(X1, X2, X3, X4)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900815 COMPILE_ASSERT(
816 !( is_non_const_reference<X1>::value ||
817 is_non_const_reference<X2>::value ||
818 is_non_const_reference<X3>::value ||
819 is_non_const_reference<X4>::value ),
820 do_not_bind_functions_with_nonconst_ref);
821
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900822 static R DoInvoke(InvokerStorageBase* base, const X3& x3, const X4& x4) {
823 StorageType* invoker = static_cast<StorageType*>(base);
824 return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
825 Unwrap(invoker->p3_), x3, x4);
826 }
827};
828
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900829// Function: Arity 6 -> 3.
830template <typename StorageType, typename R,typename X1, typename X2,
831 typename X3, typename X4, typename X5, typename X6>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900832struct Invoker3<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900833 COMPILE_ASSERT(
834 !( is_non_const_reference<X1>::value ||
835 is_non_const_reference<X2>::value ||
836 is_non_const_reference<X3>::value ||
837 is_non_const_reference<X4>::value ||
838 is_non_const_reference<X5>::value ||
839 is_non_const_reference<X6>::value ),
840 do_not_bind_functions_with_nonconst_ref);
841
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900842 static R DoInvoke(InvokerStorageBase* base, const X4& x4, const X5& x5,
843 const X6& x6) {
844 StorageType* invoker = static_cast<StorageType*>(base);
845 return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
846 Unwrap(invoker->p3_), x4, x5, x6);
847 }
848};
849
850// Method: Arity 5 -> 3.
851template <typename StorageType, typename R, typename T, typename X1,
852 typename X2, typename X3, typename X4, typename X5>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900853struct Invoker3<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900854 COMPILE_ASSERT(
855 !( is_non_const_reference<X1>::value ||
856 is_non_const_reference<X2>::value ||
857 is_non_const_reference<X3>::value ||
858 is_non_const_reference<X4>::value ||
859 is_non_const_reference<X5>::value ),
860 do_not_bind_functions_with_nonconst_ref);
861
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900862 static R DoInvoke(InvokerStorageBase* base, const X3& x3, const X4& x4,
863 const X5& x5) {
864 StorageType* invoker = static_cast<StorageType*>(base);
865 return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
866 Unwrap(invoker->p3_), x3, x4, x5);
867 }
868};
869
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900870template <typename StorageType, typename NormalizedSig>
871struct Invoker4;
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900872
873// Function: Arity 4 -> 0.
874template <typename StorageType, typename R,typename X1, typename X2,
875 typename X3, typename X4>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900876struct Invoker4<StorageType, R(*)(X1, X2, X3, X4)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900877 COMPILE_ASSERT(
878 !( is_non_const_reference<X1>::value ||
879 is_non_const_reference<X2>::value ||
880 is_non_const_reference<X3>::value ||
881 is_non_const_reference<X4>::value ),
882 do_not_bind_functions_with_nonconst_ref);
883
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900884 static R DoInvoke(InvokerStorageBase* base) {
885 StorageType* invoker = static_cast<StorageType*>(base);
886 return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
887 Unwrap(invoker->p3_), Unwrap(invoker->p4_));
888 }
889};
890
891// Method: Arity 3 -> 0.
892template <typename StorageType, typename R, typename T, typename X1,
893 typename X2, typename X3>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900894struct Invoker4<StorageType, R(T::*)(X1, X2, X3)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900895 COMPILE_ASSERT(
896 !( is_non_const_reference<X1>::value ||
897 is_non_const_reference<X2>::value ||
898 is_non_const_reference<X3>::value ),
899 do_not_bind_functions_with_nonconst_ref);
900
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900901 static R DoInvoke(InvokerStorageBase* base) {
902 StorageType* invoker = static_cast<StorageType*>(base);
903 return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
904 Unwrap(invoker->p3_), Unwrap(invoker->p4_));
905 }
906};
907
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900908// Function: Arity 5 -> 1.
909template <typename StorageType, typename R,typename X1, typename X2,
910 typename X3, typename X4, typename X5>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900911struct Invoker4<StorageType, R(*)(X1, X2, X3, X4, X5)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900912 COMPILE_ASSERT(
913 !( is_non_const_reference<X1>::value ||
914 is_non_const_reference<X2>::value ||
915 is_non_const_reference<X3>::value ||
916 is_non_const_reference<X4>::value ||
917 is_non_const_reference<X5>::value ),
918 do_not_bind_functions_with_nonconst_ref);
919
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900920 static R DoInvoke(InvokerStorageBase* base, const X5& x5) {
921 StorageType* invoker = static_cast<StorageType*>(base);
922 return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
923 Unwrap(invoker->p3_), Unwrap(invoker->p4_), x5);
924 }
925};
926
927// Method: Arity 4 -> 1.
928template <typename StorageType, typename R, typename T, typename X1,
929 typename X2, typename X3, typename X4>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900930struct Invoker4<StorageType, R(T::*)(X1, X2, X3, X4)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900931 COMPILE_ASSERT(
932 !( is_non_const_reference<X1>::value ||
933 is_non_const_reference<X2>::value ||
934 is_non_const_reference<X3>::value ||
935 is_non_const_reference<X4>::value ),
936 do_not_bind_functions_with_nonconst_ref);
937
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900938 static R DoInvoke(InvokerStorageBase* base, const X4& x4) {
939 StorageType* invoker = static_cast<StorageType*>(base);
940 return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
941 Unwrap(invoker->p3_), Unwrap(invoker->p4_), x4);
942 }
943};
944
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900945// Function: Arity 6 -> 2.
946template <typename StorageType, typename R,typename X1, typename X2,
947 typename X3, typename X4, typename X5, typename X6>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900948struct Invoker4<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900949 COMPILE_ASSERT(
950 !( is_non_const_reference<X1>::value ||
951 is_non_const_reference<X2>::value ||
952 is_non_const_reference<X3>::value ||
953 is_non_const_reference<X4>::value ||
954 is_non_const_reference<X5>::value ||
955 is_non_const_reference<X6>::value ),
956 do_not_bind_functions_with_nonconst_ref);
957
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900958 static R DoInvoke(InvokerStorageBase* base, const X5& x5, const X6& x6) {
959 StorageType* invoker = static_cast<StorageType*>(base);
960 return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
961 Unwrap(invoker->p3_), Unwrap(invoker->p4_), x5, x6);
962 }
963};
964
965// Method: Arity 5 -> 2.
966template <typename StorageType, typename R, typename T, typename X1,
967 typename X2, typename X3, typename X4, typename X5>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900968struct Invoker4<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900969 COMPILE_ASSERT(
970 !( is_non_const_reference<X1>::value ||
971 is_non_const_reference<X2>::value ||
972 is_non_const_reference<X3>::value ||
973 is_non_const_reference<X4>::value ||
974 is_non_const_reference<X5>::value ),
975 do_not_bind_functions_with_nonconst_ref);
976
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900977 static R DoInvoke(InvokerStorageBase* base, const X4& x4, const X5& x5) {
978 StorageType* invoker = static_cast<StorageType*>(base);
979 return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
980 Unwrap(invoker->p3_), Unwrap(invoker->p4_), x4, x5);
981 }
982};
983
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900984template <typename StorageType, typename NormalizedSig>
985struct Invoker5;
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900986
987// Function: Arity 5 -> 0.
988template <typename StorageType, typename R,typename X1, typename X2,
989 typename X3, typename X4, typename X5>
ajwong@chromium.orge0648232011-02-19 09:52:15 +0900990struct Invoker5<StorageType, R(*)(X1, X2, X3, X4, X5)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900991 COMPILE_ASSERT(
992 !( is_non_const_reference<X1>::value ||
993 is_non_const_reference<X2>::value ||
994 is_non_const_reference<X3>::value ||
995 is_non_const_reference<X4>::value ||
996 is_non_const_reference<X5>::value ),
997 do_not_bind_functions_with_nonconst_ref);
998
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900999 static R DoInvoke(InvokerStorageBase* base) {
1000 StorageType* invoker = static_cast<StorageType*>(base);
1001 return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
1002 Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_));
1003 }
1004};
1005
1006// Method: Arity 4 -> 0.
1007template <typename StorageType, typename R, typename T, typename X1,
1008 typename X2, typename X3, typename X4>
ajwong@chromium.orge0648232011-02-19 09:52:15 +09001009struct Invoker5<StorageType, R(T::*)(X1, X2, X3, X4)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001010 COMPILE_ASSERT(
1011 !( is_non_const_reference<X1>::value ||
1012 is_non_const_reference<X2>::value ||
1013 is_non_const_reference<X3>::value ||
1014 is_non_const_reference<X4>::value ),
1015 do_not_bind_functions_with_nonconst_ref);
1016
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001017 static R DoInvoke(InvokerStorageBase* base) {
1018 StorageType* invoker = static_cast<StorageType*>(base);
1019 return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
1020 Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_));
1021 }
1022};
1023
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001024// Function: Arity 6 -> 1.
1025template <typename StorageType, typename R,typename X1, typename X2,
1026 typename X3, typename X4, typename X5, typename X6>
ajwong@chromium.orge0648232011-02-19 09:52:15 +09001027struct Invoker5<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001028 COMPILE_ASSERT(
1029 !( is_non_const_reference<X1>::value ||
1030 is_non_const_reference<X2>::value ||
1031 is_non_const_reference<X3>::value ||
1032 is_non_const_reference<X4>::value ||
1033 is_non_const_reference<X5>::value ||
1034 is_non_const_reference<X6>::value ),
1035 do_not_bind_functions_with_nonconst_ref);
1036
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001037 static R DoInvoke(InvokerStorageBase* base, const X6& x6) {
1038 StorageType* invoker = static_cast<StorageType*>(base);
1039 return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
1040 Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_), x6);
1041 }
1042};
1043
1044// Method: Arity 5 -> 1.
1045template <typename StorageType, typename R, typename T, typename X1,
1046 typename X2, typename X3, typename X4, typename X5>
ajwong@chromium.orge0648232011-02-19 09:52:15 +09001047struct Invoker5<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001048 COMPILE_ASSERT(
1049 !( is_non_const_reference<X1>::value ||
1050 is_non_const_reference<X2>::value ||
1051 is_non_const_reference<X3>::value ||
1052 is_non_const_reference<X4>::value ||
1053 is_non_const_reference<X5>::value ),
1054 do_not_bind_functions_with_nonconst_ref);
1055
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001056 static R DoInvoke(InvokerStorageBase* base, const X5& x5) {
1057 StorageType* invoker = static_cast<StorageType*>(base);
1058 return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
1059 Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_), x5);
1060 }
1061};
1062
ajwong@chromium.orge0648232011-02-19 09:52:15 +09001063template <typename StorageType, typename NormalizedSig>
1064struct Invoker6;
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001065
1066// Function: Arity 6 -> 0.
1067template <typename StorageType, typename R,typename X1, typename X2,
1068 typename X3, typename X4, typename X5, typename X6>
ajwong@chromium.orge0648232011-02-19 09:52:15 +09001069struct Invoker6<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001070 COMPILE_ASSERT(
1071 !( is_non_const_reference<X1>::value ||
1072 is_non_const_reference<X2>::value ||
1073 is_non_const_reference<X3>::value ||
1074 is_non_const_reference<X4>::value ||
1075 is_non_const_reference<X5>::value ||
1076 is_non_const_reference<X6>::value ),
1077 do_not_bind_functions_with_nonconst_ref);
1078
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001079 static R DoInvoke(InvokerStorageBase* base) {
1080 StorageType* invoker = static_cast<StorageType*>(base);
1081 return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
1082 Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_),
1083 Unwrap(invoker->p6_));
1084 }
1085};
1086
1087// Method: Arity 5 -> 0.
1088template <typename StorageType, typename R, typename T, typename X1,
1089 typename X2, typename X3, typename X4, typename X5>
ajwong@chromium.orge0648232011-02-19 09:52:15 +09001090struct Invoker6<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001091 COMPILE_ASSERT(
1092 !( is_non_const_reference<X1>::value ||
1093 is_non_const_reference<X2>::value ||
1094 is_non_const_reference<X3>::value ||
1095 is_non_const_reference<X4>::value ||
1096 is_non_const_reference<X5>::value ),
1097 do_not_bind_functions_with_nonconst_ref);
1098
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001099 static R DoInvoke(InvokerStorageBase* base) {
1100 StorageType* invoker = static_cast<StorageType*>(base);
1101 return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
1102 Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_),
1103 Unwrap(invoker->p6_));
1104 }
1105};
1106
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001107
ajwong@chromium.orge0648232011-02-19 09:52:15 +09001108// InvokerStorageN<>
1109//
1110// These are the actual storage classes for the Invokers.
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001111//
1112// Though these types are "classes", they are being used as structs with
1113// all member variable public. We cannot make it a struct because it inherits
1114// from a class which causes a compiler warning. We cannot add a "Run()" method
1115// that forwards the unbound arguments because that would require we unwrap the
ajwong@chromium.orge0648232011-02-19 09:52:15 +09001116// Sig type like in InvokerN above to know the return type, and the arity
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001117// of Run().
1118//
ajwong@chromium.orge0648232011-02-19 09:52:15 +09001119// An alternate solution would be to merge InvokerN and InvokerStorageN,
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001120// but the generated code seemed harder to read.
1121
1122template <typename Sig>
1123class InvokerStorage0 : public InvokerStorageBase {
1124 public:
1125 typedef InvokerStorage0 StorageType;
ajwong@chromium.orge0648232011-02-19 09:52:15 +09001126 typedef FunctionTraits<Sig> TargetTraits;
1127 typedef Invoker0<StorageType, typename TargetTraits::NormalizedSig> Invoker;
1128 typedef typename TargetTraits::IsMethod IsMethod;
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001129
1130
1131 InvokerStorage0(Sig f)
1132 : f_(f) {
1133 }
1134
1135 virtual ~InvokerStorage0() { }
1136
1137 Sig f_;
1138};
1139
1140template <typename Sig, typename P1>
1141class InvokerStorage1 : public InvokerStorageBase {
1142 public:
1143 typedef InvokerStorage1 StorageType;
ajwong@chromium.orge0648232011-02-19 09:52:15 +09001144 typedef FunctionTraits<Sig> TargetTraits;
1145 typedef Invoker1<StorageType, typename TargetTraits::NormalizedSig> Invoker;
1146 typedef typename TargetTraits::IsMethod IsMethod;
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001147 // For methods, we need to be careful for parameter 1. We skip the
1148 // scoped_refptr check because the binder itself takes care of this. We also
1149 // disallow binding of an array as the method's target object.
1150 COMPILE_ASSERT(IsMethod::value ||
1151 !internal::UnsafeBindtoRefCountedArg<P1>::value,
1152 p1_is_refcounted_type_and_needs_scoped_refptr);
1153 COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
1154 first_bound_argument_to_method_cannot_be_array);
1155
1156
1157 InvokerStorage1(Sig f, const P1& p1)
1158 : f_(f), p1_(static_cast<typename BindType<P1>::StorageType>(p1)) {
1159 MaybeRefcount<IsMethod, P1>::AddRef(p1_);
1160 }
1161
1162 virtual ~InvokerStorage1() {
1163 MaybeRefcount<IsMethod, P1>::Release(p1_);
1164 }
1165
1166 Sig f_;
1167 typename BindType<P1>::StorageType p1_;
1168};
1169
1170template <typename Sig, typename P1, typename P2>
1171class InvokerStorage2 : public InvokerStorageBase {
1172 public:
1173 typedef InvokerStorage2 StorageType;
ajwong@chromium.orge0648232011-02-19 09:52:15 +09001174 typedef FunctionTraits<Sig> TargetTraits;
1175 typedef Invoker2<StorageType, typename TargetTraits::NormalizedSig> Invoker;
1176 typedef typename TargetTraits::IsMethod IsMethod;
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001177 // For methods, we need to be careful for parameter 1. We skip the
1178 // scoped_refptr check because the binder itself takes care of this. We also
1179 // disallow binding of an array as the method's target object.
1180 COMPILE_ASSERT(IsMethod::value ||
1181 !internal::UnsafeBindtoRefCountedArg<P1>::value,
1182 p1_is_refcounted_type_and_needs_scoped_refptr);
1183 COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
1184 first_bound_argument_to_method_cannot_be_array);
1185 COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P2>::value,
1186 p2_is_refcounted_type_and_needs_scoped_refptr);
1187
1188
1189 InvokerStorage2(Sig f, const P1& p1, const P2& p2)
1190 : f_(f), p1_(static_cast<typename BindType<P1>::StorageType>(p1)),
1191 p2_(static_cast<typename BindType<P2>::StorageType>(p2)) {
1192 MaybeRefcount<IsMethod, P1>::AddRef(p1_);
1193 }
1194
1195 virtual ~InvokerStorage2() {
1196 MaybeRefcount<IsMethod, P1>::Release(p1_);
1197 }
1198
1199 Sig f_;
1200 typename BindType<P1>::StorageType p1_;
1201 typename BindType<P2>::StorageType p2_;
1202};
1203
1204template <typename Sig, typename P1, typename P2, typename P3>
1205class InvokerStorage3 : public InvokerStorageBase {
1206 public:
1207 typedef InvokerStorage3 StorageType;
ajwong@chromium.orge0648232011-02-19 09:52:15 +09001208 typedef FunctionTraits<Sig> TargetTraits;
1209 typedef Invoker3<StorageType, typename TargetTraits::NormalizedSig> Invoker;
1210 typedef typename TargetTraits::IsMethod IsMethod;
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001211 // For methods, we need to be careful for parameter 1. We skip the
1212 // scoped_refptr check because the binder itself takes care of this. We also
1213 // disallow binding of an array as the method's target object.
1214 COMPILE_ASSERT(IsMethod::value ||
1215 !internal::UnsafeBindtoRefCountedArg<P1>::value,
1216 p1_is_refcounted_type_and_needs_scoped_refptr);
1217 COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
1218 first_bound_argument_to_method_cannot_be_array);
1219 COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P2>::value,
1220 p2_is_refcounted_type_and_needs_scoped_refptr);
1221 COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P3>::value,
1222 p3_is_refcounted_type_and_needs_scoped_refptr);
1223
1224
1225 InvokerStorage3(Sig f, const P1& p1, const P2& p2, const P3& p3)
1226 : f_(f), p1_(static_cast<typename BindType<P1>::StorageType>(p1)),
1227 p2_(static_cast<typename BindType<P2>::StorageType>(p2)),
1228 p3_(static_cast<typename BindType<P3>::StorageType>(p3)) {
1229 MaybeRefcount<IsMethod, P1>::AddRef(p1_);
1230 }
1231
1232 virtual ~InvokerStorage3() {
1233 MaybeRefcount<IsMethod, P1>::Release(p1_);
1234 }
1235
1236 Sig f_;
1237 typename BindType<P1>::StorageType p1_;
1238 typename BindType<P2>::StorageType p2_;
1239 typename BindType<P3>::StorageType p3_;
1240};
1241
1242template <typename Sig, typename P1, typename P2, typename P3, typename P4>
1243class InvokerStorage4 : public InvokerStorageBase {
1244 public:
1245 typedef InvokerStorage4 StorageType;
ajwong@chromium.orge0648232011-02-19 09:52:15 +09001246 typedef FunctionTraits<Sig> TargetTraits;
1247 typedef Invoker4<StorageType, typename TargetTraits::NormalizedSig> Invoker;
1248 typedef typename TargetTraits::IsMethod IsMethod;
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001249 // For methods, we need to be careful for parameter 1. We skip the
1250 // scoped_refptr check because the binder itself takes care of this. We also
1251 // disallow binding of an array as the method's target object.
1252 COMPILE_ASSERT(IsMethod::value ||
1253 !internal::UnsafeBindtoRefCountedArg<P1>::value,
1254 p1_is_refcounted_type_and_needs_scoped_refptr);
1255 COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
1256 first_bound_argument_to_method_cannot_be_array);
1257 COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P2>::value,
1258 p2_is_refcounted_type_and_needs_scoped_refptr);
1259 COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P3>::value,
1260 p3_is_refcounted_type_and_needs_scoped_refptr);
1261 COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P4>::value,
1262 p4_is_refcounted_type_and_needs_scoped_refptr);
1263
1264
1265 InvokerStorage4(Sig f, const P1& p1, const P2& p2, const P3& p3, const P4& p4)
1266 : f_(f), p1_(static_cast<typename BindType<P1>::StorageType>(p1)),
1267 p2_(static_cast<typename BindType<P2>::StorageType>(p2)),
1268 p3_(static_cast<typename BindType<P3>::StorageType>(p3)),
1269 p4_(static_cast<typename BindType<P4>::StorageType>(p4)) {
1270 MaybeRefcount<IsMethod, P1>::AddRef(p1_);
1271 }
1272
1273 virtual ~InvokerStorage4() {
1274 MaybeRefcount<IsMethod, P1>::Release(p1_);
1275 }
1276
1277 Sig f_;
1278 typename BindType<P1>::StorageType p1_;
1279 typename BindType<P2>::StorageType p2_;
1280 typename BindType<P3>::StorageType p3_;
1281 typename BindType<P4>::StorageType p4_;
1282};
1283
1284template <typename Sig, typename P1, typename P2, typename P3, typename P4,
1285 typename P5>
1286class InvokerStorage5 : public InvokerStorageBase {
1287 public:
1288 typedef InvokerStorage5 StorageType;
ajwong@chromium.orge0648232011-02-19 09:52:15 +09001289 typedef FunctionTraits<Sig> TargetTraits;
1290 typedef Invoker5<StorageType, typename TargetTraits::NormalizedSig> Invoker;
1291 typedef typename TargetTraits::IsMethod IsMethod;
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001292 // For methods, we need to be careful for parameter 1. We skip the
1293 // scoped_refptr check because the binder itself takes care of this. We also
1294 // disallow binding of an array as the method's target object.
1295 COMPILE_ASSERT(IsMethod::value ||
1296 !internal::UnsafeBindtoRefCountedArg<P1>::value,
1297 p1_is_refcounted_type_and_needs_scoped_refptr);
1298 COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
1299 first_bound_argument_to_method_cannot_be_array);
1300 COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P2>::value,
1301 p2_is_refcounted_type_and_needs_scoped_refptr);
1302 COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P3>::value,
1303 p3_is_refcounted_type_and_needs_scoped_refptr);
1304 COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P4>::value,
1305 p4_is_refcounted_type_and_needs_scoped_refptr);
1306 COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P5>::value,
1307 p5_is_refcounted_type_and_needs_scoped_refptr);
1308
1309
1310 InvokerStorage5(Sig f, const P1& p1, const P2& p2, const P3& p3,
1311 const P4& p4, const P5& p5)
1312 : f_(f), p1_(static_cast<typename BindType<P1>::StorageType>(p1)),
1313 p2_(static_cast<typename BindType<P2>::StorageType>(p2)),
1314 p3_(static_cast<typename BindType<P3>::StorageType>(p3)),
1315 p4_(static_cast<typename BindType<P4>::StorageType>(p4)),
1316 p5_(static_cast<typename BindType<P5>::StorageType>(p5)) {
1317 MaybeRefcount<IsMethod, P1>::AddRef(p1_);
1318 }
1319
1320 virtual ~InvokerStorage5() {
1321 MaybeRefcount<IsMethod, P1>::Release(p1_);
1322 }
1323
1324 Sig f_;
1325 typename BindType<P1>::StorageType p1_;
1326 typename BindType<P2>::StorageType p2_;
1327 typename BindType<P3>::StorageType p3_;
1328 typename BindType<P4>::StorageType p4_;
1329 typename BindType<P5>::StorageType p5_;
1330};
1331
1332template <typename Sig, typename P1, typename P2, typename P3, typename P4,
1333 typename P5, typename P6>
1334class InvokerStorage6 : public InvokerStorageBase {
1335 public:
1336 typedef InvokerStorage6 StorageType;
ajwong@chromium.orge0648232011-02-19 09:52:15 +09001337 typedef FunctionTraits<Sig> TargetTraits;
1338 typedef Invoker6<StorageType, typename TargetTraits::NormalizedSig> Invoker;
1339 typedef typename TargetTraits::IsMethod IsMethod;
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001340 // For methods, we need to be careful for parameter 1. We skip the
1341 // scoped_refptr check because the binder itself takes care of this. We also
1342 // disallow binding of an array as the method's target object.
1343 COMPILE_ASSERT(IsMethod::value ||
1344 !internal::UnsafeBindtoRefCountedArg<P1>::value,
1345 p1_is_refcounted_type_and_needs_scoped_refptr);
1346 COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
1347 first_bound_argument_to_method_cannot_be_array);
1348 COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P2>::value,
1349 p2_is_refcounted_type_and_needs_scoped_refptr);
1350 COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P3>::value,
1351 p3_is_refcounted_type_and_needs_scoped_refptr);
1352 COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P4>::value,
1353 p4_is_refcounted_type_and_needs_scoped_refptr);
1354 COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P5>::value,
1355 p5_is_refcounted_type_and_needs_scoped_refptr);
1356 COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P6>::value,
1357 p6_is_refcounted_type_and_needs_scoped_refptr);
1358
1359
1360 InvokerStorage6(Sig f, const P1& p1, const P2& p2, const P3& p3,
1361 const P4& p4, const P5& p5, const P6& p6)
1362 : f_(f), p1_(static_cast<typename BindType<P1>::StorageType>(p1)),
1363 p2_(static_cast<typename BindType<P2>::StorageType>(p2)),
1364 p3_(static_cast<typename BindType<P3>::StorageType>(p3)),
1365 p4_(static_cast<typename BindType<P4>::StorageType>(p4)),
1366 p5_(static_cast<typename BindType<P5>::StorageType>(p5)),
1367 p6_(static_cast<typename BindType<P6>::StorageType>(p6)) {
1368 MaybeRefcount<IsMethod, P1>::AddRef(p1_);
1369 }
1370
1371 virtual ~InvokerStorage6() {
1372 MaybeRefcount<IsMethod, P1>::Release(p1_);
1373 }
1374
1375 Sig f_;
1376 typename BindType<P1>::StorageType p1_;
1377 typename BindType<P2>::StorageType p2_;
1378 typename BindType<P3>::StorageType p3_;
1379 typename BindType<P4>::StorageType p4_;
1380 typename BindType<P5>::StorageType p5_;
1381 typename BindType<P6>::StorageType p6_;
1382};
1383
1384} // namespace internal
1385} // namespace base
1386
1387#endif // BASE_BIND_INTERNAL_H_