bind_internal.h revision dc0f95d653279beabeb9817299e2902918ba123e
1// 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"
15#include "base/callback_internal.h"
16#include "base/template_util.h"
17#include "build/build_config.h"
18
19#if defined(OS_WIN)
20#include "base/bind_internal_win.h"
21#endif
22
23namespace base {
24namespace internal {
25
26// The method by which a function is invoked is determined by 3 different
27// dimensions:
28//
29//   1) The type of function (normal or method).
30//   2) The arity of the function.
31//   3) The number of bound parameters.
32//
33// The templates below handle the determination of each of these dimensions.
34// In brief:
35//
36//   FunctionTraits<> -- Provides a normalied signature, and other traits.
37//   InvokerN<> -- Provides a DoInvoke() function that actually executes
38//                 a calback.
39//   InvokerStorageN<> -- Provides storage for the bound parameters, and
40//                        typedefs to the above.
41//
42// More details about the design of each class is included in a comment closer
43// to their defition.
44
45// FunctionTraits<>
46//
47// The FunctionTraits<> template determines the type of function, and also
48// creates a NormalizedType used to select the InvokerN classes.  It turns out
49// that syntactically, you only really have 2 variations when invoking a
50// funciton pointer: normal, and method.  One is invoked func_ptr(arg1). The
51// other is invoked (*obj_->method_ptr(arg1)).
52//
53// However, in the type system, there are many more distinctions. In standard
54// C++, there's all variations of const, and volatile on the function pointer.
55// In Windows, there are additional calling conventions (eg., __stdcall,
56// __fastcall, etc.). FunctionTraits<> handles categorizing each of these into
57// a normalized signature.
58//
59// Having a NormalizedSignature signature, reduces the combinatoric
60// complexity of defintions for the InvokerN<> later.  Even though there are
61// only 2 syntactic variations on invoking a function, without normalizing the
62// signature, there would need to be one specialization of InvokerN for each
63// unique (function_type, bound_arg, unbound_args) tuple in order to match all
64// function signatures.
65//
66// By normalizing the function signature, we reduce function_type to exactly 2.
67
68template <typename Sig>
69struct FunctionTraits;
70
71// Function: Arity 0.
72template <typename R>
73struct FunctionTraits<R(*)()> {
74  typedef R (*NormalizedSig)();
75  typedef false_type IsMethod;
76};
77
78// Method: Arity 0.
79template <typename R, typename T>
80struct FunctionTraits<R(T::*)()> {
81  typedef R (T::*NormalizedSig)();
82  typedef true_type IsMethod;
83};
84
85// Const Method: Arity 0.
86template <typename R, typename T>
87struct FunctionTraits<R(T::*)() const> {
88  typedef R (T::*NormalizedSig)();
89  typedef true_type IsMethod;
90};
91
92// Function: Arity 1.
93template <typename R, typename X1>
94struct FunctionTraits<R(*)(X1)> {
95  typedef R (*NormalizedSig)(X1);
96  typedef false_type IsMethod;
97};
98
99// Method: Arity 1.
100template <typename R, typename T, typename X1>
101struct FunctionTraits<R(T::*)(X1)> {
102  typedef R (T::*NormalizedSig)(X1);
103  typedef true_type IsMethod;
104};
105
106// Const Method: Arity 1.
107template <typename R, typename T, typename X1>
108struct FunctionTraits<R(T::*)(X1) const> {
109  typedef R (T::*NormalizedSig)(X1);
110  typedef true_type IsMethod;
111};
112
113// Function: Arity 2.
114template <typename R, typename X1, typename X2>
115struct FunctionTraits<R(*)(X1, X2)> {
116  typedef R (*NormalizedSig)(X1, X2);
117  typedef false_type IsMethod;
118};
119
120// Method: Arity 2.
121template <typename R, typename T, typename X1, typename X2>
122struct FunctionTraits<R(T::*)(X1, X2)> {
123  typedef R (T::*NormalizedSig)(X1, X2);
124  typedef true_type IsMethod;
125};
126
127// Const Method: Arity 2.
128template <typename R, typename T, typename X1, typename X2>
129struct FunctionTraits<R(T::*)(X1, X2) const> {
130  typedef R (T::*NormalizedSig)(X1, X2);
131  typedef true_type IsMethod;
132};
133
134// Function: Arity 3.
135template <typename R, typename X1, typename X2, typename X3>
136struct FunctionTraits<R(*)(X1, X2, X3)> {
137  typedef R (*NormalizedSig)(X1, X2, X3);
138  typedef false_type IsMethod;
139};
140
141// Method: Arity 3.
142template <typename R, typename T, typename X1, typename X2, typename X3>
143struct FunctionTraits<R(T::*)(X1, X2, X3)> {
144  typedef R (T::*NormalizedSig)(X1, X2, X3);
145  typedef true_type IsMethod;
146};
147
148// Const Method: Arity 3.
149template <typename R, typename T, typename X1, typename X2, typename X3>
150struct FunctionTraits<R(T::*)(X1, X2, X3) const> {
151  typedef R (T::*NormalizedSig)(X1, X2, X3);
152  typedef true_type IsMethod;
153};
154
155// Function: Arity 4.
156template <typename R, typename X1, typename X2, typename X3, typename X4>
157struct FunctionTraits<R(*)(X1, X2, X3, X4)> {
158  typedef R (*NormalizedSig)(X1, X2, X3, X4);
159  typedef false_type IsMethod;
160};
161
162// Method: Arity 4.
163template <typename R, typename T, typename X1, typename X2, typename X3,
164    typename X4>
165struct FunctionTraits<R(T::*)(X1, X2, X3, X4)> {
166  typedef R (T::*NormalizedSig)(X1, X2, X3, X4);
167  typedef true_type IsMethod;
168};
169
170// Const Method: Arity 4.
171template <typename R, typename T, typename X1, typename X2, typename X3,
172    typename X4>
173struct FunctionTraits<R(T::*)(X1, X2, X3, X4) const> {
174  typedef R (T::*NormalizedSig)(X1, X2, X3, X4);
175  typedef true_type IsMethod;
176};
177
178// Function: Arity 5.
179template <typename R, typename X1, typename X2, typename X3, typename X4,
180    typename X5>
181struct FunctionTraits<R(*)(X1, X2, X3, X4, X5)> {
182  typedef R (*NormalizedSig)(X1, X2, X3, X4, X5);
183  typedef false_type IsMethod;
184};
185
186// Method: Arity 5.
187template <typename R, typename T, typename X1, typename X2, typename X3,
188    typename X4, typename X5>
189struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5)> {
190  typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5);
191  typedef true_type IsMethod;
192};
193
194// Const Method: Arity 5.
195template <typename R, typename T, typename X1, typename X2, typename X3,
196    typename X4, typename X5>
197struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5) const> {
198  typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5);
199  typedef true_type IsMethod;
200};
201
202// Function: Arity 6.
203template <typename R, typename X1, typename X2, typename X3, typename X4,
204    typename X5, typename X6>
205struct FunctionTraits<R(*)(X1, X2, X3, X4, X5, X6)> {
206  typedef R (*NormalizedSig)(X1, X2, X3, X4, X5, X6);
207  typedef false_type IsMethod;
208};
209
210// Method: Arity 6.
211template <typename R, typename T, typename X1, typename X2, typename X3,
212    typename X4, typename X5, typename X6>
213struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5, X6)> {
214  typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5, X6);
215  typedef true_type IsMethod;
216};
217
218// Const Method: Arity 6.
219template <typename R, typename T, typename X1, typename X2, typename X3,
220    typename X4, typename X5, typename X6>
221struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5, X6) const> {
222  typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5, X6);
223  typedef true_type IsMethod;
224};
225
226// InvokerN<>
227//
228// The InvokerN templates contain a static DoInvoke() function that is the key
229// to implementing type erasure in the Callback() classes.
230//
231// DoInvoke() is a static function with a fixed signature that is independent
232// of StorageType; its first argument is a pointer to the non-templated common
233// baseclass of StorageType. This lets us store pointer to DoInvoke() in a
234// function pointer that has knowledge of the specific StorageType, and thus
235// no knowledge of the bound function and bound parameter types.
236//
237// As long as we ensure that DoInvoke() is only used with pointers there were
238// upcasted from the correct StorageType, we can be sure that execution is
239// safe.
240//
241// The InvokerN templates are the only point that knows the number of bound
242// and unbound arguments.  This is intentional because it allows the other
243// templates classes in the system to only have as many specializations as
244// the max arity of function we wish to support.
245
246template <typename StorageType, typename NormalizedSig>
247struct Invoker0;
248
249// Function: Arity 0 -> 0.
250template <typename StorageType, typename R>
251struct Invoker0<StorageType, R(*)()> {
252  static R DoInvoke(InvokerStorageBase* base) {
253    StorageType* invoker = static_cast<StorageType*>(base);
254    return invoker->f_();
255  }
256};
257
258// Function: Arity 1 -> 1.
259template <typename StorageType, typename R,typename X1>
260struct Invoker0<StorageType, R(*)(X1)> {
261  COMPILE_ASSERT(
262      !( is_non_const_reference<X1>::value ),
263      do_not_bind_functions_with_nonconst_ref);
264
265  static R DoInvoke(InvokerStorageBase* base, const X1& x1) {
266    StorageType* invoker = static_cast<StorageType*>(base);
267    return invoker->f_(x1);
268  }
269};
270
271// Function: Arity 2 -> 2.
272template <typename StorageType, typename R,typename X1, typename X2>
273struct Invoker0<StorageType, R(*)(X1, X2)> {
274  COMPILE_ASSERT(
275      !( is_non_const_reference<X1>::value ||
276          is_non_const_reference<X2>::value ),
277      do_not_bind_functions_with_nonconst_ref);
278
279  static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2) {
280    StorageType* invoker = static_cast<StorageType*>(base);
281    return invoker->f_(x1, x2);
282  }
283};
284
285// Function: Arity 3 -> 3.
286template <typename StorageType, typename R,typename X1, typename X2,
287    typename X3>
288struct Invoker0<StorageType, R(*)(X1, X2, X3)> {
289  COMPILE_ASSERT(
290      !( is_non_const_reference<X1>::value ||
291          is_non_const_reference<X2>::value ||
292          is_non_const_reference<X3>::value ),
293      do_not_bind_functions_with_nonconst_ref);
294
295  static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
296      const X3& x3) {
297    StorageType* invoker = static_cast<StorageType*>(base);
298    return invoker->f_(x1, x2, x3);
299  }
300};
301
302// Function: Arity 4 -> 4.
303template <typename StorageType, typename R,typename X1, typename X2,
304    typename X3, typename X4>
305struct Invoker0<StorageType, R(*)(X1, X2, X3, X4)> {
306  COMPILE_ASSERT(
307      !( is_non_const_reference<X1>::value ||
308          is_non_const_reference<X2>::value ||
309          is_non_const_reference<X3>::value ||
310          is_non_const_reference<X4>::value ),
311      do_not_bind_functions_with_nonconst_ref);
312
313  static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
314      const X3& x3, const X4& x4) {
315    StorageType* invoker = static_cast<StorageType*>(base);
316    return invoker->f_(x1, x2, x3, x4);
317  }
318};
319
320// Function: Arity 5 -> 5.
321template <typename StorageType, typename R,typename X1, typename X2,
322    typename X3, typename X4, typename X5>
323struct Invoker0<StorageType, R(*)(X1, X2, X3, X4, X5)> {
324  COMPILE_ASSERT(
325      !( is_non_const_reference<X1>::value ||
326          is_non_const_reference<X2>::value ||
327          is_non_const_reference<X3>::value ||
328          is_non_const_reference<X4>::value ||
329          is_non_const_reference<X5>::value ),
330      do_not_bind_functions_with_nonconst_ref);
331
332  static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
333      const X3& x3, const X4& x4, const X5& x5) {
334    StorageType* invoker = static_cast<StorageType*>(base);
335    return invoker->f_(x1, x2, x3, x4, x5);
336  }
337};
338
339// Function: Arity 6 -> 6.
340template <typename StorageType, typename R,typename X1, typename X2,
341    typename X3, typename X4, typename X5, typename X6>
342struct Invoker0<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
343  COMPILE_ASSERT(
344      !( is_non_const_reference<X1>::value ||
345          is_non_const_reference<X2>::value ||
346          is_non_const_reference<X3>::value ||
347          is_non_const_reference<X4>::value ||
348          is_non_const_reference<X5>::value ||
349          is_non_const_reference<X6>::value ),
350      do_not_bind_functions_with_nonconst_ref);
351
352  static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
353      const X3& x3, const X4& x4, const X5& x5, const X6& x6) {
354    StorageType* invoker = static_cast<StorageType*>(base);
355    return invoker->f_(x1, x2, x3, x4, x5, x6);
356  }
357};
358
359template <typename StorageType, typename NormalizedSig>
360struct Invoker1;
361
362// Function: Arity 1 -> 0.
363template <typename StorageType, typename R,typename X1>
364struct Invoker1<StorageType, R(*)(X1)> {
365  COMPILE_ASSERT(
366      !( is_non_const_reference<X1>::value ),
367      do_not_bind_functions_with_nonconst_ref);
368
369  static R DoInvoke(InvokerStorageBase* base) {
370    StorageType* invoker = static_cast<StorageType*>(base);
371    return invoker->f_(Unwrap(invoker->p1_));
372  }
373};
374
375// Method: Arity 0 -> 0.
376template <typename StorageType, typename R, typename T>
377struct Invoker1<StorageType, R(T::*)()> {
378  static R DoInvoke(InvokerStorageBase* base) {
379    StorageType* invoker = static_cast<StorageType*>(base);
380    return (Unwrap(invoker->p1_)->*invoker->f_)();
381  }
382};
383
384// Function: Arity 2 -> 1.
385template <typename StorageType, typename R,typename X1, typename X2>
386struct Invoker1<StorageType, R(*)(X1, X2)> {
387  COMPILE_ASSERT(
388      !( is_non_const_reference<X1>::value ||
389          is_non_const_reference<X2>::value ),
390      do_not_bind_functions_with_nonconst_ref);
391
392  static R DoInvoke(InvokerStorageBase* base, const X2& x2) {
393    StorageType* invoker = static_cast<StorageType*>(base);
394    return invoker->f_(Unwrap(invoker->p1_), x2);
395  }
396};
397
398// Method: Arity 1 -> 1.
399template <typename StorageType, typename R, typename T, typename X1>
400struct Invoker1<StorageType, R(T::*)(X1)> {
401  COMPILE_ASSERT(
402      !( is_non_const_reference<X1>::value ),
403      do_not_bind_functions_with_nonconst_ref);
404
405  static R DoInvoke(InvokerStorageBase* base, const X1& x1) {
406    StorageType* invoker = static_cast<StorageType*>(base);
407    return (Unwrap(invoker->p1_)->*invoker->f_)(x1);
408  }
409};
410
411// Function: Arity 3 -> 2.
412template <typename StorageType, typename R,typename X1, typename X2,
413    typename X3>
414struct Invoker1<StorageType, R(*)(X1, X2, X3)> {
415  COMPILE_ASSERT(
416      !( is_non_const_reference<X1>::value ||
417          is_non_const_reference<X2>::value ||
418          is_non_const_reference<X3>::value ),
419      do_not_bind_functions_with_nonconst_ref);
420
421  static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3) {
422    StorageType* invoker = static_cast<StorageType*>(base);
423    return invoker->f_(Unwrap(invoker->p1_), x2, x3);
424  }
425};
426
427// Method: Arity 2 -> 2.
428template <typename StorageType, typename R, typename T, typename X1,
429    typename X2>
430struct Invoker1<StorageType, R(T::*)(X1, X2)> {
431  COMPILE_ASSERT(
432      !( is_non_const_reference<X1>::value ||
433          is_non_const_reference<X2>::value ),
434      do_not_bind_functions_with_nonconst_ref);
435
436  static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2) {
437    StorageType* invoker = static_cast<StorageType*>(base);
438    return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2);
439  }
440};
441
442// Function: Arity 4 -> 3.
443template <typename StorageType, typename R,typename X1, typename X2,
444    typename X3, typename X4>
445struct Invoker1<StorageType, R(*)(X1, X2, X3, X4)> {
446  COMPILE_ASSERT(
447      !( is_non_const_reference<X1>::value ||
448          is_non_const_reference<X2>::value ||
449          is_non_const_reference<X3>::value ||
450          is_non_const_reference<X4>::value ),
451      do_not_bind_functions_with_nonconst_ref);
452
453  static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3,
454      const X4& x4) {
455    StorageType* invoker = static_cast<StorageType*>(base);
456    return invoker->f_(Unwrap(invoker->p1_), x2, x3, x4);
457  }
458};
459
460// Method: Arity 3 -> 3.
461template <typename StorageType, typename R, typename T, typename X1,
462    typename X2, typename X3>
463struct Invoker1<StorageType, R(T::*)(X1, X2, X3)> {
464  COMPILE_ASSERT(
465      !( is_non_const_reference<X1>::value ||
466          is_non_const_reference<X2>::value ||
467          is_non_const_reference<X3>::value ),
468      do_not_bind_functions_with_nonconst_ref);
469
470  static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
471      const X3& x3) {
472    StorageType* invoker = static_cast<StorageType*>(base);
473    return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2, x3);
474  }
475};
476
477// Function: Arity 5 -> 4.
478template <typename StorageType, typename R,typename X1, typename X2,
479    typename X3, typename X4, typename X5>
480struct Invoker1<StorageType, R(*)(X1, X2, X3, X4, X5)> {
481  COMPILE_ASSERT(
482      !( is_non_const_reference<X1>::value ||
483          is_non_const_reference<X2>::value ||
484          is_non_const_reference<X3>::value ||
485          is_non_const_reference<X4>::value ||
486          is_non_const_reference<X5>::value ),
487      do_not_bind_functions_with_nonconst_ref);
488
489  static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3,
490      const X4& x4, const X5& x5) {
491    StorageType* invoker = static_cast<StorageType*>(base);
492    return invoker->f_(Unwrap(invoker->p1_), x2, x3, x4, x5);
493  }
494};
495
496// Method: Arity 4 -> 4.
497template <typename StorageType, typename R, typename T, typename X1,
498    typename X2, typename X3, typename X4>
499struct Invoker1<StorageType, R(T::*)(X1, X2, X3, X4)> {
500  COMPILE_ASSERT(
501      !( is_non_const_reference<X1>::value ||
502          is_non_const_reference<X2>::value ||
503          is_non_const_reference<X3>::value ||
504          is_non_const_reference<X4>::value ),
505      do_not_bind_functions_with_nonconst_ref);
506
507  static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
508      const X3& x3, const X4& x4) {
509    StorageType* invoker = static_cast<StorageType*>(base);
510    return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2, x3, x4);
511  }
512};
513
514// Function: Arity 6 -> 5.
515template <typename StorageType, typename R,typename X1, typename X2,
516    typename X3, typename X4, typename X5, typename X6>
517struct Invoker1<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
518  COMPILE_ASSERT(
519      !( is_non_const_reference<X1>::value ||
520          is_non_const_reference<X2>::value ||
521          is_non_const_reference<X3>::value ||
522          is_non_const_reference<X4>::value ||
523          is_non_const_reference<X5>::value ||
524          is_non_const_reference<X6>::value ),
525      do_not_bind_functions_with_nonconst_ref);
526
527  static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3,
528      const X4& x4, const X5& x5, const X6& x6) {
529    StorageType* invoker = static_cast<StorageType*>(base);
530    return invoker->f_(Unwrap(invoker->p1_), x2, x3, x4, x5, x6);
531  }
532};
533
534// Method: Arity 5 -> 5.
535template <typename StorageType, typename R, typename T, typename X1,
536    typename X2, typename X3, typename X4, typename X5>
537struct Invoker1<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
538  COMPILE_ASSERT(
539      !( is_non_const_reference<X1>::value ||
540          is_non_const_reference<X2>::value ||
541          is_non_const_reference<X3>::value ||
542          is_non_const_reference<X4>::value ||
543          is_non_const_reference<X5>::value ),
544      do_not_bind_functions_with_nonconst_ref);
545
546  static R DoInvoke(InvokerStorageBase* base, const X1& x1, const X2& x2,
547      const X3& x3, const X4& x4, const X5& x5) {
548    StorageType* invoker = static_cast<StorageType*>(base);
549    return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2, x3, x4, x5);
550  }
551};
552
553template <typename StorageType, typename NormalizedSig>
554struct Invoker2;
555
556// Function: Arity 2 -> 0.
557template <typename StorageType, typename R,typename X1, typename X2>
558struct Invoker2<StorageType, R(*)(X1, X2)> {
559  COMPILE_ASSERT(
560      !( is_non_const_reference<X1>::value ||
561          is_non_const_reference<X2>::value ),
562      do_not_bind_functions_with_nonconst_ref);
563
564  static R DoInvoke(InvokerStorageBase* base) {
565    StorageType* invoker = static_cast<StorageType*>(base);
566    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_));
567  }
568};
569
570// Method: Arity 1 -> 0.
571template <typename StorageType, typename R, typename T, typename X1>
572struct Invoker2<StorageType, R(T::*)(X1)> {
573  COMPILE_ASSERT(
574      !( is_non_const_reference<X1>::value ),
575      do_not_bind_functions_with_nonconst_ref);
576
577  static R DoInvoke(InvokerStorageBase* base) {
578    StorageType* invoker = static_cast<StorageType*>(base);
579    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_));
580  }
581};
582
583// Function: Arity 3 -> 1.
584template <typename StorageType, typename R,typename X1, typename X2,
585    typename X3>
586struct Invoker2<StorageType, R(*)(X1, X2, X3)> {
587  COMPILE_ASSERT(
588      !( is_non_const_reference<X1>::value ||
589          is_non_const_reference<X2>::value ||
590          is_non_const_reference<X3>::value ),
591      do_not_bind_functions_with_nonconst_ref);
592
593  static R DoInvoke(InvokerStorageBase* base, const X3& x3) {
594    StorageType* invoker = static_cast<StorageType*>(base);
595    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3);
596  }
597};
598
599// Method: Arity 2 -> 1.
600template <typename StorageType, typename R, typename T, typename X1,
601    typename X2>
602struct Invoker2<StorageType, R(T::*)(X1, X2)> {
603  COMPILE_ASSERT(
604      !( is_non_const_reference<X1>::value ||
605          is_non_const_reference<X2>::value ),
606      do_not_bind_functions_with_nonconst_ref);
607
608  static R DoInvoke(InvokerStorageBase* base, const X2& x2) {
609    StorageType* invoker = static_cast<StorageType*>(base);
610    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2);
611  }
612};
613
614// Function: Arity 4 -> 2.
615template <typename StorageType, typename R,typename X1, typename X2,
616    typename X3, typename X4>
617struct Invoker2<StorageType, R(*)(X1, X2, X3, X4)> {
618  COMPILE_ASSERT(
619      !( is_non_const_reference<X1>::value ||
620          is_non_const_reference<X2>::value ||
621          is_non_const_reference<X3>::value ||
622          is_non_const_reference<X4>::value ),
623      do_not_bind_functions_with_nonconst_ref);
624
625  static R DoInvoke(InvokerStorageBase* base, const X3& x3, const X4& x4) {
626    StorageType* invoker = static_cast<StorageType*>(base);
627    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3, x4);
628  }
629};
630
631// Method: Arity 3 -> 2.
632template <typename StorageType, typename R, typename T, typename X1,
633    typename X2, typename X3>
634struct Invoker2<StorageType, R(T::*)(X1, X2, X3)> {
635  COMPILE_ASSERT(
636      !( is_non_const_reference<X1>::value ||
637          is_non_const_reference<X2>::value ||
638          is_non_const_reference<X3>::value ),
639      do_not_bind_functions_with_nonconst_ref);
640
641  static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3) {
642    StorageType* invoker = static_cast<StorageType*>(base);
643    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2, x3);
644  }
645};
646
647// Function: Arity 5 -> 3.
648template <typename StorageType, typename R,typename X1, typename X2,
649    typename X3, typename X4, typename X5>
650struct Invoker2<StorageType, R(*)(X1, X2, X3, X4, X5)> {
651  COMPILE_ASSERT(
652      !( is_non_const_reference<X1>::value ||
653          is_non_const_reference<X2>::value ||
654          is_non_const_reference<X3>::value ||
655          is_non_const_reference<X4>::value ||
656          is_non_const_reference<X5>::value ),
657      do_not_bind_functions_with_nonconst_ref);
658
659  static R DoInvoke(InvokerStorageBase* base, const X3& x3, const X4& x4,
660      const X5& x5) {
661    StorageType* invoker = static_cast<StorageType*>(base);
662    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3, x4, x5);
663  }
664};
665
666// Method: Arity 4 -> 3.
667template <typename StorageType, typename R, typename T, typename X1,
668    typename X2, typename X3, typename X4>
669struct Invoker2<StorageType, R(T::*)(X1, X2, X3, X4)> {
670  COMPILE_ASSERT(
671      !( is_non_const_reference<X1>::value ||
672          is_non_const_reference<X2>::value ||
673          is_non_const_reference<X3>::value ||
674          is_non_const_reference<X4>::value ),
675      do_not_bind_functions_with_nonconst_ref);
676
677  static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3,
678      const X4& x4) {
679    StorageType* invoker = static_cast<StorageType*>(base);
680    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2, x3,
681        x4);
682  }
683};
684
685// Function: Arity 6 -> 4.
686template <typename StorageType, typename R,typename X1, typename X2,
687    typename X3, typename X4, typename X5, typename X6>
688struct Invoker2<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
689  COMPILE_ASSERT(
690      !( is_non_const_reference<X1>::value ||
691          is_non_const_reference<X2>::value ||
692          is_non_const_reference<X3>::value ||
693          is_non_const_reference<X4>::value ||
694          is_non_const_reference<X5>::value ||
695          is_non_const_reference<X6>::value ),
696      do_not_bind_functions_with_nonconst_ref);
697
698  static R DoInvoke(InvokerStorageBase* base, const X3& x3, const X4& x4,
699      const X5& x5, const X6& x6) {
700    StorageType* invoker = static_cast<StorageType*>(base);
701    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3, x4, x5,
702        x6);
703  }
704};
705
706// Method: Arity 5 -> 4.
707template <typename StorageType, typename R, typename T, typename X1,
708    typename X2, typename X3, typename X4, typename X5>
709struct Invoker2<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
710  COMPILE_ASSERT(
711      !( is_non_const_reference<X1>::value ||
712          is_non_const_reference<X2>::value ||
713          is_non_const_reference<X3>::value ||
714          is_non_const_reference<X4>::value ||
715          is_non_const_reference<X5>::value ),
716      do_not_bind_functions_with_nonconst_ref);
717
718  static R DoInvoke(InvokerStorageBase* base, const X2& x2, const X3& x3,
719      const X4& x4, const X5& x5) {
720    StorageType* invoker = static_cast<StorageType*>(base);
721    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2, x3,
722        x4, x5);
723  }
724};
725
726template <typename StorageType, typename NormalizedSig>
727struct Invoker3;
728
729// Function: Arity 3 -> 0.
730template <typename StorageType, typename R,typename X1, typename X2,
731    typename X3>
732struct Invoker3<StorageType, R(*)(X1, X2, X3)> {
733  COMPILE_ASSERT(
734      !( is_non_const_reference<X1>::value ||
735          is_non_const_reference<X2>::value ||
736          is_non_const_reference<X3>::value ),
737      do_not_bind_functions_with_nonconst_ref);
738
739  static R DoInvoke(InvokerStorageBase* base) {
740    StorageType* invoker = static_cast<StorageType*>(base);
741    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
742        Unwrap(invoker->p3_));
743  }
744};
745
746// Method: Arity 2 -> 0.
747template <typename StorageType, typename R, typename T, typename X1,
748    typename X2>
749struct Invoker3<StorageType, R(T::*)(X1, X2)> {
750  COMPILE_ASSERT(
751      !( is_non_const_reference<X1>::value ||
752          is_non_const_reference<X2>::value ),
753      do_not_bind_functions_with_nonconst_ref);
754
755  static R DoInvoke(InvokerStorageBase* base) {
756    StorageType* invoker = static_cast<StorageType*>(base);
757    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
758        Unwrap(invoker->p3_));
759  }
760};
761
762// Function: Arity 4 -> 1.
763template <typename StorageType, typename R,typename X1, typename X2,
764    typename X3, typename X4>
765struct Invoker3<StorageType, R(*)(X1, X2, X3, X4)> {
766  COMPILE_ASSERT(
767      !( is_non_const_reference<X1>::value ||
768          is_non_const_reference<X2>::value ||
769          is_non_const_reference<X3>::value ||
770          is_non_const_reference<X4>::value ),
771      do_not_bind_functions_with_nonconst_ref);
772
773  static R DoInvoke(InvokerStorageBase* base, const X4& x4) {
774    StorageType* invoker = static_cast<StorageType*>(base);
775    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
776        Unwrap(invoker->p3_), x4);
777  }
778};
779
780// Method: Arity 3 -> 1.
781template <typename StorageType, typename R, typename T, typename X1,
782    typename X2, typename X3>
783struct Invoker3<StorageType, R(T::*)(X1, X2, X3)> {
784  COMPILE_ASSERT(
785      !( is_non_const_reference<X1>::value ||
786          is_non_const_reference<X2>::value ||
787          is_non_const_reference<X3>::value ),
788      do_not_bind_functions_with_nonconst_ref);
789
790  static R DoInvoke(InvokerStorageBase* base, const X3& x3) {
791    StorageType* invoker = static_cast<StorageType*>(base);
792    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
793        Unwrap(invoker->p3_), x3);
794  }
795};
796
797// Function: Arity 5 -> 2.
798template <typename StorageType, typename R,typename X1, typename X2,
799    typename X3, typename X4, typename X5>
800struct Invoker3<StorageType, R(*)(X1, X2, X3, X4, X5)> {
801  COMPILE_ASSERT(
802      !( is_non_const_reference<X1>::value ||
803          is_non_const_reference<X2>::value ||
804          is_non_const_reference<X3>::value ||
805          is_non_const_reference<X4>::value ||
806          is_non_const_reference<X5>::value ),
807      do_not_bind_functions_with_nonconst_ref);
808
809  static R DoInvoke(InvokerStorageBase* base, const X4& x4, const X5& x5) {
810    StorageType* invoker = static_cast<StorageType*>(base);
811    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
812        Unwrap(invoker->p3_), x4, x5);
813  }
814};
815
816// Method: Arity 4 -> 2.
817template <typename StorageType, typename R, typename T, typename X1,
818    typename X2, typename X3, typename X4>
819struct Invoker3<StorageType, R(T::*)(X1, X2, X3, X4)> {
820  COMPILE_ASSERT(
821      !( is_non_const_reference<X1>::value ||
822          is_non_const_reference<X2>::value ||
823          is_non_const_reference<X3>::value ||
824          is_non_const_reference<X4>::value ),
825      do_not_bind_functions_with_nonconst_ref);
826
827  static R DoInvoke(InvokerStorageBase* base, const X3& x3, const X4& x4) {
828    StorageType* invoker = static_cast<StorageType*>(base);
829    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
830        Unwrap(invoker->p3_), x3, x4);
831  }
832};
833
834// Function: Arity 6 -> 3.
835template <typename StorageType, typename R,typename X1, typename X2,
836    typename X3, typename X4, typename X5, typename X6>
837struct Invoker3<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
838  COMPILE_ASSERT(
839      !( is_non_const_reference<X1>::value ||
840          is_non_const_reference<X2>::value ||
841          is_non_const_reference<X3>::value ||
842          is_non_const_reference<X4>::value ||
843          is_non_const_reference<X5>::value ||
844          is_non_const_reference<X6>::value ),
845      do_not_bind_functions_with_nonconst_ref);
846
847  static R DoInvoke(InvokerStorageBase* base, const X4& x4, const X5& x5,
848      const X6& x6) {
849    StorageType* invoker = static_cast<StorageType*>(base);
850    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
851        Unwrap(invoker->p3_), x4, x5, x6);
852  }
853};
854
855// Method: Arity 5 -> 3.
856template <typename StorageType, typename R, typename T, typename X1,
857    typename X2, typename X3, typename X4, typename X5>
858struct Invoker3<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
859  COMPILE_ASSERT(
860      !( is_non_const_reference<X1>::value ||
861          is_non_const_reference<X2>::value ||
862          is_non_const_reference<X3>::value ||
863          is_non_const_reference<X4>::value ||
864          is_non_const_reference<X5>::value ),
865      do_not_bind_functions_with_nonconst_ref);
866
867  static R DoInvoke(InvokerStorageBase* base, const X3& x3, const X4& x4,
868      const X5& x5) {
869    StorageType* invoker = static_cast<StorageType*>(base);
870    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
871        Unwrap(invoker->p3_), x3, x4, x5);
872  }
873};
874
875template <typename StorageType, typename NormalizedSig>
876struct Invoker4;
877
878// Function: Arity 4 -> 0.
879template <typename StorageType, typename R,typename X1, typename X2,
880    typename X3, typename X4>
881struct Invoker4<StorageType, R(*)(X1, X2, X3, X4)> {
882  COMPILE_ASSERT(
883      !( is_non_const_reference<X1>::value ||
884          is_non_const_reference<X2>::value ||
885          is_non_const_reference<X3>::value ||
886          is_non_const_reference<X4>::value ),
887      do_not_bind_functions_with_nonconst_ref);
888
889  static R DoInvoke(InvokerStorageBase* base) {
890    StorageType* invoker = static_cast<StorageType*>(base);
891    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
892        Unwrap(invoker->p3_), Unwrap(invoker->p4_));
893  }
894};
895
896// Method: Arity 3 -> 0.
897template <typename StorageType, typename R, typename T, typename X1,
898    typename X2, typename X3>
899struct Invoker4<StorageType, R(T::*)(X1, X2, X3)> {
900  COMPILE_ASSERT(
901      !( is_non_const_reference<X1>::value ||
902          is_non_const_reference<X2>::value ||
903          is_non_const_reference<X3>::value ),
904      do_not_bind_functions_with_nonconst_ref);
905
906  static R DoInvoke(InvokerStorageBase* base) {
907    StorageType* invoker = static_cast<StorageType*>(base);
908    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
909        Unwrap(invoker->p3_), Unwrap(invoker->p4_));
910  }
911};
912
913// Function: Arity 5 -> 1.
914template <typename StorageType, typename R,typename X1, typename X2,
915    typename X3, typename X4, typename X5>
916struct Invoker4<StorageType, R(*)(X1, X2, X3, X4, X5)> {
917  COMPILE_ASSERT(
918      !( is_non_const_reference<X1>::value ||
919          is_non_const_reference<X2>::value ||
920          is_non_const_reference<X3>::value ||
921          is_non_const_reference<X4>::value ||
922          is_non_const_reference<X5>::value ),
923      do_not_bind_functions_with_nonconst_ref);
924
925  static R DoInvoke(InvokerStorageBase* base, const X5& x5) {
926    StorageType* invoker = static_cast<StorageType*>(base);
927    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
928        Unwrap(invoker->p3_), Unwrap(invoker->p4_), x5);
929  }
930};
931
932// Method: Arity 4 -> 1.
933template <typename StorageType, typename R, typename T, typename X1,
934    typename X2, typename X3, typename X4>
935struct Invoker4<StorageType, R(T::*)(X1, X2, X3, X4)> {
936  COMPILE_ASSERT(
937      !( is_non_const_reference<X1>::value ||
938          is_non_const_reference<X2>::value ||
939          is_non_const_reference<X3>::value ||
940          is_non_const_reference<X4>::value ),
941      do_not_bind_functions_with_nonconst_ref);
942
943  static R DoInvoke(InvokerStorageBase* base, const X4& x4) {
944    StorageType* invoker = static_cast<StorageType*>(base);
945    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
946        Unwrap(invoker->p3_), Unwrap(invoker->p4_), x4);
947  }
948};
949
950// Function: Arity 6 -> 2.
951template <typename StorageType, typename R,typename X1, typename X2,
952    typename X3, typename X4, typename X5, typename X6>
953struct Invoker4<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
954  COMPILE_ASSERT(
955      !( is_non_const_reference<X1>::value ||
956          is_non_const_reference<X2>::value ||
957          is_non_const_reference<X3>::value ||
958          is_non_const_reference<X4>::value ||
959          is_non_const_reference<X5>::value ||
960          is_non_const_reference<X6>::value ),
961      do_not_bind_functions_with_nonconst_ref);
962
963  static R DoInvoke(InvokerStorageBase* base, const X5& x5, const X6& x6) {
964    StorageType* invoker = static_cast<StorageType*>(base);
965    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
966        Unwrap(invoker->p3_), Unwrap(invoker->p4_), x5, x6);
967  }
968};
969
970// Method: Arity 5 -> 2.
971template <typename StorageType, typename R, typename T, typename X1,
972    typename X2, typename X3, typename X4, typename X5>
973struct Invoker4<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
974  COMPILE_ASSERT(
975      !( is_non_const_reference<X1>::value ||
976          is_non_const_reference<X2>::value ||
977          is_non_const_reference<X3>::value ||
978          is_non_const_reference<X4>::value ||
979          is_non_const_reference<X5>::value ),
980      do_not_bind_functions_with_nonconst_ref);
981
982  static R DoInvoke(InvokerStorageBase* base, const X4& x4, const X5& x5) {
983    StorageType* invoker = static_cast<StorageType*>(base);
984    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
985        Unwrap(invoker->p3_), Unwrap(invoker->p4_), x4, x5);
986  }
987};
988
989template <typename StorageType, typename NormalizedSig>
990struct Invoker5;
991
992// Function: Arity 5 -> 0.
993template <typename StorageType, typename R,typename X1, typename X2,
994    typename X3, typename X4, typename X5>
995struct Invoker5<StorageType, R(*)(X1, X2, X3, X4, X5)> {
996  COMPILE_ASSERT(
997      !( is_non_const_reference<X1>::value ||
998          is_non_const_reference<X2>::value ||
999          is_non_const_reference<X3>::value ||
1000          is_non_const_reference<X4>::value ||
1001          is_non_const_reference<X5>::value ),
1002      do_not_bind_functions_with_nonconst_ref);
1003
1004  static R DoInvoke(InvokerStorageBase* base) {
1005    StorageType* invoker = static_cast<StorageType*>(base);
1006    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
1007        Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_));
1008  }
1009};
1010
1011// Method: Arity 4 -> 0.
1012template <typename StorageType, typename R, typename T, typename X1,
1013    typename X2, typename X3, typename X4>
1014struct Invoker5<StorageType, R(T::*)(X1, X2, X3, X4)> {
1015  COMPILE_ASSERT(
1016      !( is_non_const_reference<X1>::value ||
1017          is_non_const_reference<X2>::value ||
1018          is_non_const_reference<X3>::value ||
1019          is_non_const_reference<X4>::value ),
1020      do_not_bind_functions_with_nonconst_ref);
1021
1022  static R DoInvoke(InvokerStorageBase* base) {
1023    StorageType* invoker = static_cast<StorageType*>(base);
1024    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
1025        Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_));
1026  }
1027};
1028
1029// Function: Arity 6 -> 1.
1030template <typename StorageType, typename R,typename X1, typename X2,
1031    typename X3, typename X4, typename X5, typename X6>
1032struct Invoker5<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
1033  COMPILE_ASSERT(
1034      !( is_non_const_reference<X1>::value ||
1035          is_non_const_reference<X2>::value ||
1036          is_non_const_reference<X3>::value ||
1037          is_non_const_reference<X4>::value ||
1038          is_non_const_reference<X5>::value ||
1039          is_non_const_reference<X6>::value ),
1040      do_not_bind_functions_with_nonconst_ref);
1041
1042  static R DoInvoke(InvokerStorageBase* base, const X6& x6) {
1043    StorageType* invoker = static_cast<StorageType*>(base);
1044    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
1045        Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_), x6);
1046  }
1047};
1048
1049// Method: Arity 5 -> 1.
1050template <typename StorageType, typename R, typename T, typename X1,
1051    typename X2, typename X3, typename X4, typename X5>
1052struct Invoker5<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
1053  COMPILE_ASSERT(
1054      !( is_non_const_reference<X1>::value ||
1055          is_non_const_reference<X2>::value ||
1056          is_non_const_reference<X3>::value ||
1057          is_non_const_reference<X4>::value ||
1058          is_non_const_reference<X5>::value ),
1059      do_not_bind_functions_with_nonconst_ref);
1060
1061  static R DoInvoke(InvokerStorageBase* base, const X5& x5) {
1062    StorageType* invoker = static_cast<StorageType*>(base);
1063    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
1064        Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_), x5);
1065  }
1066};
1067
1068template <typename StorageType, typename NormalizedSig>
1069struct Invoker6;
1070
1071// Function: Arity 6 -> 0.
1072template <typename StorageType, typename R,typename X1, typename X2,
1073    typename X3, typename X4, typename X5, typename X6>
1074struct Invoker6<StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
1075  COMPILE_ASSERT(
1076      !( is_non_const_reference<X1>::value ||
1077          is_non_const_reference<X2>::value ||
1078          is_non_const_reference<X3>::value ||
1079          is_non_const_reference<X4>::value ||
1080          is_non_const_reference<X5>::value ||
1081          is_non_const_reference<X6>::value ),
1082      do_not_bind_functions_with_nonconst_ref);
1083
1084  static R DoInvoke(InvokerStorageBase* base) {
1085    StorageType* invoker = static_cast<StorageType*>(base);
1086    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
1087        Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_),
1088        Unwrap(invoker->p6_));
1089  }
1090};
1091
1092// Method: Arity 5 -> 0.
1093template <typename StorageType, typename R, typename T, typename X1,
1094    typename X2, typename X3, typename X4, typename X5>
1095struct Invoker6<StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
1096  COMPILE_ASSERT(
1097      !( is_non_const_reference<X1>::value ||
1098          is_non_const_reference<X2>::value ||
1099          is_non_const_reference<X3>::value ||
1100          is_non_const_reference<X4>::value ||
1101          is_non_const_reference<X5>::value ),
1102      do_not_bind_functions_with_nonconst_ref);
1103
1104  static R DoInvoke(InvokerStorageBase* base) {
1105    StorageType* invoker = static_cast<StorageType*>(base);
1106    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
1107        Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_),
1108        Unwrap(invoker->p6_));
1109  }
1110};
1111
1112
1113// InvokerStorageN<>
1114//
1115// These are the actual storage classes for the Invokers.
1116//
1117// Though these types are "classes", they are being used as structs with
1118// all member variable public.  We cannot make it a struct because it inherits
1119// from a class which causes a compiler warning.  We cannot add a "Run()" method
1120// that forwards the unbound arguments because that would require we unwrap the
1121// Sig type like in InvokerN above to know the return type, and the arity
1122// of Run().
1123//
1124// An alternate solution would be to merge InvokerN and InvokerStorageN,
1125// but the generated code seemed harder to read.
1126
1127template <typename Sig>
1128class InvokerStorage0 : public InvokerStorageBase {
1129 public:
1130  typedef InvokerStorage0 StorageType;
1131  typedef FunctionTraits<Sig> TargetTraits;
1132  typedef Invoker0<StorageType, typename TargetTraits::NormalizedSig> Invoker;
1133  typedef typename TargetTraits::IsMethod IsMethod;
1134
1135
1136  InvokerStorage0(Sig f)
1137      : f_(f) {
1138  }
1139
1140  virtual ~InvokerStorage0() {  }
1141
1142  Sig f_;
1143};
1144
1145template <typename Sig, typename P1>
1146class InvokerStorage1 : public InvokerStorageBase {
1147 public:
1148  typedef InvokerStorage1 StorageType;
1149  typedef FunctionTraits<Sig> TargetTraits;
1150  typedef Invoker1<StorageType, typename TargetTraits::NormalizedSig> Invoker;
1151  typedef typename TargetTraits::IsMethod IsMethod;
1152  // For methods, we need to be careful for parameter 1.  We skip the
1153  // scoped_refptr check because the binder itself takes care of this. We also
1154  // disallow binding of an array as the method's target object.
1155  COMPILE_ASSERT(IsMethod::value ||
1156                 !internal::UnsafeBindtoRefCountedArg<P1>::value,
1157                 p1_is_refcounted_type_and_needs_scoped_refptr);
1158  COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
1159                 first_bound_argument_to_method_cannot_be_array);
1160
1161
1162  InvokerStorage1(Sig f, const P1& p1)
1163      : f_(f), p1_(static_cast<typename BindType<P1>::StorageType>(p1)) {
1164    MaybeRefcount<IsMethod, P1>::AddRef(p1_);
1165  }
1166
1167  virtual ~InvokerStorage1() {
1168    MaybeRefcount<IsMethod, P1>::Release(p1_);
1169  }
1170
1171  Sig f_;
1172  typename BindType<P1>::StorageType p1_;
1173};
1174
1175template <typename Sig, typename P1, typename P2>
1176class InvokerStorage2 : public InvokerStorageBase {
1177 public:
1178  typedef InvokerStorage2 StorageType;
1179  typedef FunctionTraits<Sig> TargetTraits;
1180  typedef Invoker2<StorageType, typename TargetTraits::NormalizedSig> Invoker;
1181  typedef typename TargetTraits::IsMethod IsMethod;
1182  // For methods, we need to be careful for parameter 1.  We skip the
1183  // scoped_refptr check because the binder itself takes care of this. We also
1184  // disallow binding of an array as the method's target object.
1185  COMPILE_ASSERT(IsMethod::value ||
1186                 !internal::UnsafeBindtoRefCountedArg<P1>::value,
1187                 p1_is_refcounted_type_and_needs_scoped_refptr);
1188  COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
1189                 first_bound_argument_to_method_cannot_be_array);
1190  COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P2>::value,
1191                 p2_is_refcounted_type_and_needs_scoped_refptr);
1192
1193
1194  InvokerStorage2(Sig f, const P1& p1, const P2& p2)
1195      : f_(f), p1_(static_cast<typename BindType<P1>::StorageType>(p1)),
1196          p2_(static_cast<typename BindType<P2>::StorageType>(p2)) {
1197    MaybeRefcount<IsMethod, P1>::AddRef(p1_);
1198  }
1199
1200  virtual ~InvokerStorage2() {
1201    MaybeRefcount<IsMethod, P1>::Release(p1_);
1202  }
1203
1204  Sig f_;
1205  typename BindType<P1>::StorageType p1_;
1206  typename BindType<P2>::StorageType p2_;
1207};
1208
1209template <typename Sig, typename P1, typename P2, typename P3>
1210class InvokerStorage3 : public InvokerStorageBase {
1211 public:
1212  typedef InvokerStorage3 StorageType;
1213  typedef FunctionTraits<Sig> TargetTraits;
1214  typedef Invoker3<StorageType, typename TargetTraits::NormalizedSig> Invoker;
1215  typedef typename TargetTraits::IsMethod IsMethod;
1216  // For methods, we need to be careful for parameter 1.  We skip the
1217  // scoped_refptr check because the binder itself takes care of this. We also
1218  // disallow binding of an array as the method's target object.
1219  COMPILE_ASSERT(IsMethod::value ||
1220                 !internal::UnsafeBindtoRefCountedArg<P1>::value,
1221                 p1_is_refcounted_type_and_needs_scoped_refptr);
1222  COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
1223                 first_bound_argument_to_method_cannot_be_array);
1224  COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P2>::value,
1225                 p2_is_refcounted_type_and_needs_scoped_refptr);
1226  COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P3>::value,
1227                 p3_is_refcounted_type_and_needs_scoped_refptr);
1228
1229
1230  InvokerStorage3(Sig f, const P1& p1, const P2& p2, const P3& p3)
1231      : f_(f), p1_(static_cast<typename BindType<P1>::StorageType>(p1)),
1232          p2_(static_cast<typename BindType<P2>::StorageType>(p2)),
1233          p3_(static_cast<typename BindType<P3>::StorageType>(p3)) {
1234    MaybeRefcount<IsMethod, P1>::AddRef(p1_);
1235  }
1236
1237  virtual ~InvokerStorage3() {
1238    MaybeRefcount<IsMethod, P1>::Release(p1_);
1239  }
1240
1241  Sig f_;
1242  typename BindType<P1>::StorageType p1_;
1243  typename BindType<P2>::StorageType p2_;
1244  typename BindType<P3>::StorageType p3_;
1245};
1246
1247template <typename Sig, typename P1, typename P2, typename P3, typename P4>
1248class InvokerStorage4 : public InvokerStorageBase {
1249 public:
1250  typedef InvokerStorage4 StorageType;
1251  typedef FunctionTraits<Sig> TargetTraits;
1252  typedef Invoker4<StorageType, typename TargetTraits::NormalizedSig> Invoker;
1253  typedef typename TargetTraits::IsMethod IsMethod;
1254  // For methods, we need to be careful for parameter 1.  We skip the
1255  // scoped_refptr check because the binder itself takes care of this. We also
1256  // disallow binding of an array as the method's target object.
1257  COMPILE_ASSERT(IsMethod::value ||
1258                 !internal::UnsafeBindtoRefCountedArg<P1>::value,
1259                 p1_is_refcounted_type_and_needs_scoped_refptr);
1260  COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
1261                 first_bound_argument_to_method_cannot_be_array);
1262  COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P2>::value,
1263                 p2_is_refcounted_type_and_needs_scoped_refptr);
1264  COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P3>::value,
1265                 p3_is_refcounted_type_and_needs_scoped_refptr);
1266  COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P4>::value,
1267                 p4_is_refcounted_type_and_needs_scoped_refptr);
1268
1269
1270  InvokerStorage4(Sig f, const P1& p1, const P2& p2, const P3& p3, const P4& p4)
1271      : f_(f), p1_(static_cast<typename BindType<P1>::StorageType>(p1)),
1272          p2_(static_cast<typename BindType<P2>::StorageType>(p2)),
1273          p3_(static_cast<typename BindType<P3>::StorageType>(p3)),
1274          p4_(static_cast<typename BindType<P4>::StorageType>(p4)) {
1275    MaybeRefcount<IsMethod, P1>::AddRef(p1_);
1276  }
1277
1278  virtual ~InvokerStorage4() {
1279    MaybeRefcount<IsMethod, P1>::Release(p1_);
1280  }
1281
1282  Sig f_;
1283  typename BindType<P1>::StorageType p1_;
1284  typename BindType<P2>::StorageType p2_;
1285  typename BindType<P3>::StorageType p3_;
1286  typename BindType<P4>::StorageType p4_;
1287};
1288
1289template <typename Sig, typename P1, typename P2, typename P3, typename P4,
1290    typename P5>
1291class InvokerStorage5 : public InvokerStorageBase {
1292 public:
1293  typedef InvokerStorage5 StorageType;
1294  typedef FunctionTraits<Sig> TargetTraits;
1295  typedef Invoker5<StorageType, typename TargetTraits::NormalizedSig> Invoker;
1296  typedef typename TargetTraits::IsMethod IsMethod;
1297  // For methods, we need to be careful for parameter 1.  We skip the
1298  // scoped_refptr check because the binder itself takes care of this. We also
1299  // disallow binding of an array as the method's target object.
1300  COMPILE_ASSERT(IsMethod::value ||
1301                 !internal::UnsafeBindtoRefCountedArg<P1>::value,
1302                 p1_is_refcounted_type_and_needs_scoped_refptr);
1303  COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
1304                 first_bound_argument_to_method_cannot_be_array);
1305  COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P2>::value,
1306                 p2_is_refcounted_type_and_needs_scoped_refptr);
1307  COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P3>::value,
1308                 p3_is_refcounted_type_and_needs_scoped_refptr);
1309  COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P4>::value,
1310                 p4_is_refcounted_type_and_needs_scoped_refptr);
1311  COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P5>::value,
1312                 p5_is_refcounted_type_and_needs_scoped_refptr);
1313
1314
1315  InvokerStorage5(Sig f, const P1& p1, const P2& p2, const P3& p3,
1316      const P4& p4, const P5& p5)
1317      : f_(f), p1_(static_cast<typename BindType<P1>::StorageType>(p1)),
1318          p2_(static_cast<typename BindType<P2>::StorageType>(p2)),
1319          p3_(static_cast<typename BindType<P3>::StorageType>(p3)),
1320          p4_(static_cast<typename BindType<P4>::StorageType>(p4)),
1321          p5_(static_cast<typename BindType<P5>::StorageType>(p5)) {
1322    MaybeRefcount<IsMethod, P1>::AddRef(p1_);
1323  }
1324
1325  virtual ~InvokerStorage5() {
1326    MaybeRefcount<IsMethod, P1>::Release(p1_);
1327  }
1328
1329  Sig f_;
1330  typename BindType<P1>::StorageType p1_;
1331  typename BindType<P2>::StorageType p2_;
1332  typename BindType<P3>::StorageType p3_;
1333  typename BindType<P4>::StorageType p4_;
1334  typename BindType<P5>::StorageType p5_;
1335};
1336
1337template <typename Sig, typename P1, typename P2, typename P3, typename P4,
1338    typename P5, typename P6>
1339class InvokerStorage6 : public InvokerStorageBase {
1340 public:
1341  typedef InvokerStorage6 StorageType;
1342  typedef FunctionTraits<Sig> TargetTraits;
1343  typedef Invoker6<StorageType, typename TargetTraits::NormalizedSig> Invoker;
1344  typedef typename TargetTraits::IsMethod IsMethod;
1345  // For methods, we need to be careful for parameter 1.  We skip the
1346  // scoped_refptr check because the binder itself takes care of this. We also
1347  // disallow binding of an array as the method's target object.
1348  COMPILE_ASSERT(IsMethod::value ||
1349                 !internal::UnsafeBindtoRefCountedArg<P1>::value,
1350                 p1_is_refcounted_type_and_needs_scoped_refptr);
1351  COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
1352                 first_bound_argument_to_method_cannot_be_array);
1353  COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P2>::value,
1354                 p2_is_refcounted_type_and_needs_scoped_refptr);
1355  COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P3>::value,
1356                 p3_is_refcounted_type_and_needs_scoped_refptr);
1357  COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P4>::value,
1358                 p4_is_refcounted_type_and_needs_scoped_refptr);
1359  COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P5>::value,
1360                 p5_is_refcounted_type_and_needs_scoped_refptr);
1361  COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P6>::value,
1362                 p6_is_refcounted_type_and_needs_scoped_refptr);
1363
1364
1365  InvokerStorage6(Sig f, const P1& p1, const P2& p2, const P3& p3,
1366      const P4& p4, const P5& p5, const P6& p6)
1367      : f_(f), p1_(static_cast<typename BindType<P1>::StorageType>(p1)),
1368          p2_(static_cast<typename BindType<P2>::StorageType>(p2)),
1369          p3_(static_cast<typename BindType<P3>::StorageType>(p3)),
1370          p4_(static_cast<typename BindType<P4>::StorageType>(p4)),
1371          p5_(static_cast<typename BindType<P5>::StorageType>(p5)),
1372          p6_(static_cast<typename BindType<P6>::StorageType>(p6)) {
1373    MaybeRefcount<IsMethod, P1>::AddRef(p1_);
1374  }
1375
1376  virtual ~InvokerStorage6() {
1377    MaybeRefcount<IsMethod, P1>::Release(p1_);
1378  }
1379
1380  Sig f_;
1381  typename BindType<P1>::StorageType p1_;
1382  typename BindType<P2>::StorageType p2_;
1383  typename BindType<P3>::StorageType p3_;
1384  typename BindType<P4>::StorageType p4_;
1385  typename BindType<P5>::StorageType p5_;
1386  typename BindType<P6>::StorageType p6_;
1387};
1388
1389}  // namespace internal
1390}  // namespace base
1391
1392#endif  // BASE_BIND_INTERNAL_H_
1393