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