Home | History | Annotate | Download | only in base
      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