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