bind_internal.h revision ddb351dbec246cf1fab5ec20d2d5520909041de1
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
24namespace base {
25namespace 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
69template <typename Sig>
70struct FunctionTraits;
71
72// Function: Arity 0.
73template <typename R>
74struct FunctionTraits<R(*)()> {
75  typedef R (*NormalizedSig)();
76  typedef false_type IsMethod;
77
78};
79
80// Method: Arity 0.
81template <typename R, typename T>
82struct 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.
92template <typename R, typename T>
93struct 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.
103template <typename R, typename X1>
104struct 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.
113template <typename R, typename T, typename X1>
114struct 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.
125template <typename R, typename T, typename X1>
126struct 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.
137template <typename R, typename X1, typename X2>
138struct 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.
148template <typename R, typename T, typename X1, typename X2>
149struct 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.
161template <typename R, typename T, typename X1, typename X2>
162struct 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.
174template <typename R, typename X1, typename X2, typename X3>
175struct 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.
186template <typename R, typename T, typename X1, typename X2, typename X3>
187struct 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.
200template <typename R, typename T, typename X1, typename X2, typename X3>
201struct 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.
214template <typename R, typename X1, typename X2, typename X3, typename X4>
215struct 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.
227template <typename R, typename T, typename X1, typename X2, typename X3,
228    typename X4>
229struct 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.
243template <typename R, typename T, typename X1, typename X2, typename X3,
244    typename X4>
245struct 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.
259template <typename R, typename X1, typename X2, typename X3, typename X4,
260    typename X5>
261struct 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.
274template <typename R, typename T, typename X1, typename X2, typename X3,
275    typename X4, typename X5>
276struct 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.
291template <typename R, typename T, typename X1, typename X2, typename X3,
292    typename X4, typename X5>
293struct 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.
308template <typename R, typename X1, typename X2, typename X3, typename X4,
309    typename X5, typename X6>
310struct 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.
324template <typename R, typename T, typename X1, typename X2, typename X3,
325    typename X4, typename X5, typename X6>
326struct 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.
342template <typename R, typename T, typename X1, typename X2, typename X3,
343    typename X4, typename X5, typename X6>
344struct 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
379template <typename StorageType, typename NormalizedSig>
380struct Invoker0;
381
382// Function: Arity 0 -> 0.
383template <typename StorageType, typename R>
384struct 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.
392template <typename StorageType, typename R,typename X1>
393struct 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.
402template <typename StorageType, typename R,typename X1, typename X2>
403struct 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.
413template <typename StorageType, typename R,typename X1, typename X2,
414    typename X3>
415struct 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.
426template <typename StorageType, typename R,typename X1, typename X2,
427    typename X3, typename X4>
428struct 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.
440template <typename StorageType, typename R,typename X1, typename X2,
441    typename X3, typename X4, typename X5>
442struct 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.
455template <typename StorageType, typename R,typename X1, typename X2,
456    typename X3, typename X4, typename X5, typename X6>
457struct 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
470template <typename StorageType, typename NormalizedSig>
471struct Invoker1;
472
473// Function: Arity 1 -> 0.
474template <typename StorageType, typename R,typename X1>
475struct 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.
483template <typename StorageType, typename R, typename T>
484struct 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.
492template <typename StorageType, typename R,typename X1, typename X2>
493struct 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.
502template <typename StorageType, typename R, typename T, typename X1>
503struct 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.
512template <typename StorageType, typename R,typename X1, typename X2,
513    typename X3>
514struct 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.
524template <typename StorageType, typename R, typename T, typename X1,
525    typename X2>
526struct 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.
536template <typename StorageType, typename R,typename X1, typename X2,
537    typename X3, typename X4>
538struct 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.
549template <typename StorageType, typename R, typename T, typename X1,
550    typename X2, typename X3>
551struct 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.
562template <typename StorageType, typename R,typename X1, typename X2,
563    typename X3, typename X4, typename X5>
564struct 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.
576template <typename StorageType, typename R, typename T, typename X1,
577    typename X2, typename X3, typename X4>
578struct 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.
590template <typename StorageType, typename R,typename X1, typename X2,
591    typename X3, typename X4, typename X5, typename X6>
592struct 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.
605template <typename StorageType, typename R, typename T, typename X1,
606    typename X2, typename X3, typename X4, typename X5>
607struct 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
619template <typename StorageType, typename NormalizedSig>
620struct Invoker2;
621
622// Function: Arity 2 -> 0.
623template <typename StorageType, typename R,typename X1, typename X2>
624struct 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.
632template <typename StorageType, typename R, typename T, typename X1>
633struct 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.
641template <typename StorageType, typename R,typename X1, typename X2,
642    typename X3>
643struct 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.
652template <typename StorageType, typename R, typename T, typename X1,
653    typename X2>
654struct 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.
663template <typename StorageType, typename R,typename X1, typename X2,
664    typename X3, typename X4>
665struct 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.
675template <typename StorageType, typename R, typename T, typename X1,
676    typename X2, typename X3>
677struct 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.
687template <typename StorageType, typename R,typename X1, typename X2,
688    typename X3, typename X4, typename X5>
689struct 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.
700template <typename StorageType, typename R, typename T, typename X1,
701    typename X2, typename X3, typename X4>
702struct 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.
714template <typename StorageType, typename R,typename X1, typename X2,
715    typename X3, typename X4, typename X5, typename X6>
716struct 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.
729template <typename StorageType, typename R, typename T, typename X1,
730    typename X2, typename X3, typename X4, typename X5>
731struct 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
743template <typename StorageType, typename NormalizedSig>
744struct Invoker3;
745
746// Function: Arity 3 -> 0.
747template <typename StorageType, typename R,typename X1, typename X2,
748    typename X3>
749struct 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.
758template <typename StorageType, typename R, typename T, typename X1,
759    typename X2>
760struct 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.
769template <typename StorageType, typename R,typename X1, typename X2,
770    typename X3, typename X4>
771struct 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.
781template <typename StorageType, typename R, typename T, typename X1,
782    typename X2, typename X3>
783struct 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.
793template <typename StorageType, typename R,typename X1, typename X2,
794    typename X3, typename X4, typename X5>
795struct 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.
806template <typename StorageType, typename R, typename T, typename X1,
807    typename X2, typename X3, typename X4>
808struct 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.
819template <typename StorageType, typename R,typename X1, typename X2,
820    typename X3, typename X4, typename X5, typename X6>
821struct 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.
833template <typename StorageType, typename R, typename T, typename X1,
834    typename X2, typename X3, typename X4, typename X5>
835struct 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
846template <typename StorageType, typename NormalizedSig>
847struct Invoker4;
848
849// Function: Arity 4 -> 0.
850template <typename StorageType, typename R,typename X1, typename X2,
851    typename X3, typename X4>
852struct 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.
861template <typename StorageType, typename R, typename T, typename X1,
862    typename X2, typename X3>
863struct 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.
872template <typename StorageType, typename R,typename X1, typename X2,
873    typename X3, typename X4, typename X5>
874struct 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.
884template <typename StorageType, typename R, typename T, typename X1,
885    typename X2, typename X3, typename X4>
886struct 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.
896template <typename StorageType, typename R,typename X1, typename X2,
897    typename X3, typename X4, typename X5, typename X6>
898struct 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.
909template <typename StorageType, typename R, typename T, typename X1,
910    typename X2, typename X3, typename X4, typename X5>
911struct 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
921template <typename StorageType, typename NormalizedSig>
922struct Invoker5;
923
924// Function: Arity 5 -> 0.
925template <typename StorageType, typename R,typename X1, typename X2,
926    typename X3, typename X4, typename X5>
927struct 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.
936template <typename StorageType, typename R, typename T, typename X1,
937    typename X2, typename X3, typename X4>
938struct 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.
947template <typename StorageType, typename R,typename X1, typename X2,
948    typename X3, typename X4, typename X5, typename X6>
949struct 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.
959template <typename StorageType, typename R, typename T, typename X1,
960    typename X2, typename X3, typename X4, typename X5>
961struct 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
970template <typename StorageType, typename NormalizedSig>
971struct Invoker6;
972
973// Function: Arity 6 -> 0.
974template <typename StorageType, typename R,typename X1, typename X2,
975    typename X3, typename X4, typename X5, typename X6>
976struct 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.
986template <typename StorageType, typename R, typename T, typename X1,
987    typename X2, typename X3, typename X4, typename X5>
988struct 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
1012template <typename Sig>
1013class 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
1031template <typename Sig, typename P1>
1032class 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
1071template <typename Sig, typename P1, typename P2>
1072class 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
1116template <typename Sig, typename P1, typename P2, typename P3>
1117class 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
1166template <typename Sig, typename P1, typename P2, typename P3, typename P4>
1167class 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
1221template <typename Sig, typename P1, typename P2, typename P3, typename P4,
1222    typename P5>
1223class 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
1283template <typename Sig, typename P1, typename P2, typename P3, typename P4,
1284    typename P5, typename P6>
1285class 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