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