trunk/src/emu/delegate.h
| r18528 | r18529 | |
| 133 | 133 | // HELPER CLASSES |
| 134 | 134 | //************************************************************************** |
| 135 | 135 | |
| 136 | // generic function type |
| 137 | typedef void (*delegate_generic_function)(); |
| 138 | |
| 139 | |
| 136 | 140 | // ======================> generic_class |
| 137 | 141 | |
| 138 | 142 | // define a dummy generic class that is just straight single-inheritance |
| r18528 | r18529 | |
| 233 | 237 | |
| 234 | 238 | |
| 235 | 239 | //************************************************************************** |
| 240 | // DELEGATE MEMBER FUNCTION POINTER WRAPPERS |
| 241 | //************************************************************************** |
| 242 | |
| 243 | #if (USE_DELEGATE_TYPE == DELEGATE_TYPE_COMPATIBLE) |
| 244 | |
| 245 | // ======================> delegate_mfp |
| 246 | |
| 247 | // delegate_mfp is a class that wraps a generic member function pointer |
| 248 | // in a static buffer, and can effectively recast itself back for later use; |
| 249 | // it hides some of the gross details involved in copying artibtrary member |
| 250 | // function pointers around |
| 251 | struct delegate_mfp |
| 252 | { |
| 253 | // default constructor |
| 254 | delegate_mfp() { memset(&m_rawdata, 0, sizeof(m_rawdata)); } |
| 255 | |
| 256 | // copy constructor |
| 257 | delegate_mfp(const delegate_mfp &src) |
| 258 | : m_rawdata(src.m_rawdata) { } |
| 259 | |
| 260 | // construct from any member function pointer |
| 261 | template<typename _FunctionType> |
| 262 | delegate_mfp(_FunctionType mfp) |
| 263 | { |
| 264 | assert(sizeof(mfp) <= sizeof(m_rawdata)); |
| 265 | memset(&m_rawdata, 0, sizeof(m_rawdata)); |
| 266 | *reinterpret_cast<_FunctionType *>(&m_rawdata) = mfp; |
| 267 | } |
| 268 | |
| 269 | // assignment operator |
| 270 | delegate_mfp &operator=(const delegate_mfp &src) |
| 271 | { |
| 272 | if (this != &src) |
| 273 | m_rawdata = src.m_rawdata; |
| 274 | return *this; |
| 275 | } |
| 276 | |
| 277 | // comparison operator |
| 278 | bool operator==(const delegate_mfp &rhs) const |
| 279 | { |
| 280 | return (memcmp(&m_rawdata, &rhs.m_rawdata, sizeof(m_rawdata)) == 0); |
| 281 | } |
| 282 | |
| 283 | // isnull checker |
| 284 | bool isnull() const |
| 285 | { |
| 286 | for (int index = 0; index < ARRAY_LENGTH(m_rawdata.data); index++) |
| 287 | if (m_rawdata.data[index] != 0) |
| 288 | return false; |
| 289 | return true; |
| 290 | } |
| 291 | |
| 292 | // convert back to a member function pointer |
| 293 | template<class _FunctionType> |
| 294 | _FunctionType &mfp() const { return *reinterpret_cast<_FunctionType *>(&m_rawdata); } |
| 295 | |
| 296 | // for MSVC maximum size is one pointer, plus 3 ints; |
| 297 | // all other implementations seem to be smaller |
| 298 | static const int MAX_MFP_SIZE = sizeof(void *) + 3 * sizeof(int); |
| 299 | |
| 300 | // raw buffer to hold the copy of the function pointer |
| 301 | mutable struct { int data[(MAX_MFP_SIZE + sizeof(int) - 1) / sizeof(int)]; } m_rawdata; |
| 302 | }; |
| 303 | |
| 304 | #elif (USE_DELEGATE_TYPE == DELEGATE_TYPE_INTERNAL) |
| 305 | |
| 306 | // ======================> delegate_mfp |
| 307 | |
| 308 | // struct describing the contents of a member function pointer |
| 309 | struct delegate_mfp |
| 310 | { |
| 311 | // default constructor |
| 312 | delegate_mfp() |
| 313 | : m_function(0), |
| 314 | m_this_delta(0) { } |
| 315 | |
| 316 | // copy constructor |
| 317 | delegate_mfp(const delegate_mfp &src) |
| 318 | : m_function(src.m_function), |
| 319 | m_this_delta(src.m_this_delta) { } |
| 320 | |
| 321 | // construct from any member function pointer |
| 322 | template<typename _FunctionPtr> |
| 323 | delegate_mfp(_FunctionPtr mfp) |
| 324 | { |
| 325 | assert(sizeof(mfp) == sizeof(*this)); |
| 326 | *reinterpret_cast<_FunctionPtr *>(this) = mfp; |
| 327 | } |
| 328 | |
| 329 | // assignment operator |
| 330 | delegate_mfp &operator=(const delegate_mfp &src) |
| 331 | { |
| 332 | if (this != &src) |
| 333 | { |
| 334 | m_function = src.m_function; |
| 335 | m_this_delta = src.m_this_delta; |
| 336 | } |
| 337 | return *this; |
| 338 | } |
| 339 | |
| 340 | // comparison operator |
| 341 | bool operator==(const delegate_mfp &rhs) const |
| 342 | { |
| 343 | return (m_function == rhs.m_function && m_this_delta == rhs.m_this_delta); |
| 344 | } |
| 345 | |
| 346 | // isnull checker |
| 347 | bool isnull() const { return (m_function == 0); } |
| 348 | |
| 349 | // extract the generic function and adjust the object pointer |
| 350 | delegate_generic_function convert_to_generic(delegate_generic_class *&object) const; |
| 351 | |
| 352 | // actual state |
| 353 | FPTR m_function; // first item can be one of two things: |
| 354 | // if even, it's a pointer to the function |
| 355 | // if odd, it's the byte offset into the vtable |
| 356 | int m_this_delta; // delta to apply to the 'this' pointer |
| 357 | }; |
| 358 | |
| 359 | #endif |
| 360 | |
| 361 | |
| 362 | //************************************************************************** |
| 236 | 363 | // COMMON DELEGATE BASE CLASS |
| 237 | 364 | //************************************************************************** |
| 238 | 365 | |
| r18528 | r18529 | |
| 245 | 372 | typedef delegate_generic_class *(*late_bind_func)(delegate_late_bind &object); |
| 246 | 373 | |
| 247 | 374 | // construction |
| 248 | | delegate_common_base(const char *name = NULL, late_bind_func latebinder = NULL, delegate_generic_class *object = NULL) |
| 375 | delegate_common_base(const char *name = NULL, late_bind_func latebinder = NULL, delegate_generic_function funcptr = NULL) |
| 249 | 376 | : m_name(name), |
| 250 | | m_object(object), |
| 251 | | m_latebinder(latebinder) { } |
| 377 | m_object(NULL), |
| 378 | m_latebinder(latebinder), |
| 379 | m_raw_function(funcptr) { } |
| 252 | 380 | |
| 381 | template<typename _FunctionPtr> |
| 382 | delegate_common_base(const char *name, late_bind_func latebinder, _FunctionPtr funcptr) |
| 383 | : m_name(name), |
| 384 | m_object(NULL), |
| 385 | m_latebinder(latebinder), |
| 386 | m_raw_function(NULL), |
| 387 | m_raw_mfp(funcptr) { } |
| 388 | |
| 389 | // copy constructor |
| 253 | 390 | delegate_common_base(const delegate_common_base &src) |
| 254 | 391 | : m_name(src.m_name), |
| 255 | 392 | m_object(src.m_object), |
| 256 | | m_latebinder(src.m_latebinder) { } |
| 393 | m_latebinder(src.m_latebinder), |
| 394 | m_raw_function(src.m_raw_function), |
| 395 | m_raw_mfp(src.m_raw_mfp) { } |
| 257 | 396 | |
| 397 | // copy helper |
| 398 | void copy(const delegate_common_base &src) |
| 399 | { |
| 400 | m_name = src.m_name; |
| 401 | m_object = src.m_object; |
| 402 | m_latebinder = src.m_latebinder; |
| 403 | m_raw_function = src.m_raw_function; |
| 404 | m_raw_mfp = src.m_raw_mfp; |
| 405 | } |
| 406 | |
| 258 | 407 | public: |
| 259 | 408 | // getters |
| 260 | 409 | bool has_object() const { return (m_object != NULL); } |
| 261 | 410 | const char *name() const { return m_name; } |
| 411 | |
| 412 | // helpers |
| 413 | bool isnull() const { return (m_raw_function == NULL && m_raw_mfp.isnull()); } |
| 414 | bool is_mfp() const { return !m_raw_mfp.isnull(); } |
| 262 | 415 | |
| 416 | // comparison helper |
| 417 | bool operator==(const delegate_common_base &rhs) const |
| 418 | { |
| 419 | return (m_object == rhs.m_object && m_raw_function == rhs.m_raw_function && m_raw_mfp == rhs.m_raw_mfp); |
| 420 | } |
| 421 | |
| 263 | 422 | protected: |
| 264 | 423 | // late binding helper |
| 265 | 424 | template<class _FunctionClass> |
| r18528 | r18529 | |
| 275 | 434 | const char * m_name; // name string |
| 276 | 435 | delegate_generic_class * m_object; // pointer to the post-cast object |
| 277 | 436 | late_bind_func m_latebinder; // late binding helper |
| 437 | delegate_generic_function m_raw_function; // raw static function pointer |
| 438 | delegate_mfp m_raw_mfp; // raw member function pointer |
| 278 | 439 | }; |
| 279 | 440 | |
| 280 | 441 | |
| r18528 | r18529 | |
| 285 | 446 | |
| 286 | 447 | #if (USE_DELEGATE_TYPE == DELEGATE_TYPE_COMPATIBLE) |
| 287 | 448 | |
| 288 | | // ======================> delegate_raw_mfp |
| 289 | | |
| 290 | | // delegate_raw_mfp is a class that wraps a generic member function pointer |
| 291 | | // in a static buffer, and can effectively recast itself back for later use; |
| 292 | | // it hides some of the gross details involved in copying artibtrary member |
| 293 | | // function pointers around |
| 294 | | struct delegate_raw_mfp |
| 295 | | { |
| 296 | | // for MSVC maximum size is one pointer, plus 3 ints |
| 297 | | static const int MAX_MFP_SIZE = sizeof(void *) + 3 * sizeof(int); |
| 298 | | |
| 299 | | // default and copy constructors |
| 300 | | delegate_raw_mfp() { memset(&m_rawdata, 0, sizeof(m_rawdata)); } |
| 301 | | delegate_raw_mfp(const delegate_raw_mfp &src) : m_rawdata(src.m_rawdata) { } |
| 302 | | |
| 303 | | // construct from any member function pointer |
| 304 | | template<typename _FunctionType> |
| 305 | | delegate_raw_mfp(_FunctionType mfp) |
| 306 | | { |
| 307 | | assert(sizeof(mfp) <= sizeof(m_rawdata)); |
| 308 | | memset(&m_rawdata, 0, sizeof(m_rawdata)); |
| 309 | | *reinterpret_cast<_FunctionType *>(&m_rawdata) = mfp; |
| 310 | | } |
| 311 | | |
| 312 | | // assignment operator |
| 313 | | delegate_raw_mfp &operator=(const delegate_raw_mfp &src) |
| 314 | | { |
| 315 | | if (this != &src) |
| 316 | | m_rawdata = src.m_rawdata; |
| 317 | | return *this; |
| 318 | | } |
| 319 | | |
| 320 | | // comparison operator |
| 321 | | bool operator==(const delegate_raw_mfp &rhs) const |
| 322 | | { |
| 323 | | return (memcmp(&m_rawdata, &rhs.m_rawdata, sizeof(m_rawdata)) == 0); |
| 324 | | } |
| 325 | | |
| 326 | | // convert back to a member function pointer |
| 327 | | template<class _FunctionType> |
| 328 | | _FunctionType &mfp() const { return *reinterpret_cast<_FunctionType *>(&m_rawdata); } |
| 329 | | |
| 330 | | // raw buffer to hold the copy of the function pointer |
| 331 | | mutable struct { UINT8 bytes[MAX_MFP_SIZE]; } m_rawdata; |
| 332 | | }; |
| 333 | | |
| 334 | | |
| 335 | 449 | // ======================> delegate_base |
| 336 | 450 | |
| 337 | 451 | // general delegate class template supporting up to 4 parameters |
| r18528 | r18529 | |
| 358 | 472 | delegate_base(const delegate_base &src) |
| 359 | 473 | : delegate_common_base(src), |
| 360 | 474 | m_function(src.m_function), |
| 361 | | m_callobject(src.is_mfp() ? reinterpret_cast<delegate_generic_class *>(this) : src.m_object), |
| 362 | | m_rawfunction(src.m_rawfunction) { } |
| 475 | m_callobject(src.is_mfp() ? reinterpret_cast<delegate_generic_class *>(this) : src.m_object) { } |
| 363 | 476 | |
| 364 | 477 | // copy constructor with late bind |
| 365 | 478 | delegate_base(const delegate_base &src, delegate_late_bind &object) |
| 366 | 479 | : delegate_common_base(src), |
| 367 | 480 | m_function(src.m_function), |
| 368 | | m_callobject(src.is_mfp() ? reinterpret_cast<delegate_generic_class *>(this) : src.m_object), |
| 369 | | m_rawfunction(src.m_rawfunction) |
| 481 | m_callobject(src.is_mfp() ? reinterpret_cast<delegate_generic_class *>(this) : src.m_object) |
| 370 | 482 | { |
| 371 | 483 | late_bind(object); |
| 372 | 484 | } |
| r18528 | r18529 | |
| 374 | 486 | // construct from member function with object pointer |
| 375 | 487 | template<class _FunctionClass> |
| 376 | 488 | delegate_base(typename traits<_FunctionClass>::member_func_type funcptr, const char *name, _FunctionClass *object) |
| 377 | | : delegate_common_base(name, &late_bind_helper<_FunctionClass>), |
| 489 | : delegate_common_base(name, &late_bind_helper<_FunctionClass>, funcptr), |
| 378 | 490 | m_function(&delegate_base::method_stub<_FunctionClass>), |
| 379 | | m_callobject(reinterpret_cast<delegate_generic_class *>(this)), |
| 380 | | m_rawfunction(funcptr) |
| 491 | m_callobject(reinterpret_cast<delegate_generic_class *>(this)) |
| 381 | 492 | { |
| 382 | 493 | bind(reinterpret_cast<delegate_generic_class *>(object)); |
| 383 | 494 | } |
| r18528 | r18529 | |
| 385 | 496 | // construct from static function with object pointer |
| 386 | 497 | template<class _FunctionClass> |
| 387 | 498 | delegate_base(typename traits<_FunctionClass>::static_func_type funcptr, const char *name, _FunctionClass *object) |
| 388 | | : delegate_common_base(name, &late_bind_helper<_FunctionClass>), |
| 499 | : delegate_common_base(name, &late_bind_helper<_FunctionClass>, reinterpret_cast<delegate_generic_function>(funcptr)), |
| 389 | 500 | m_function(reinterpret_cast<generic_static_func>(funcptr)), |
| 390 | 501 | m_callobject(NULL) |
| 391 | 502 | { |
| r18528 | r18529 | |
| 395 | 506 | // construct from static reference function with object pointer |
| 396 | 507 | template<class _FunctionClass> |
| 397 | 508 | delegate_base(typename traits<_FunctionClass>::static_ref_func_type funcptr, const char *name, _FunctionClass *object) |
| 398 | | : delegate_common_base(name, &late_bind_helper<_FunctionClass>), |
| 509 | : delegate_common_base(name, &late_bind_helper<_FunctionClass>, reinterpret_cast<delegate_generic_function>(funcptr)), |
| 399 | 510 | m_function(reinterpret_cast<generic_static_func>(funcptr)), |
| 400 | 511 | m_callobject(NULL) |
| 401 | 512 | { |
| r18528 | r18529 | |
| 407 | 518 | { |
| 408 | 519 | if (this != &src) |
| 409 | 520 | { |
| 410 | | m_name = src.m_name; |
| 411 | | m_object = src.m_object; |
| 521 | delegate_common_base::copy(src); |
| 412 | 522 | m_callobject = src.is_mfp() ? reinterpret_cast<delegate_generic_class *>(this) : src.m_object; |
| 413 | 523 | m_function = src.m_function; |
| 414 | | m_rawfunction = src.m_rawfunction; |
| 415 | | m_latebinder = src.m_latebinder; |
| 416 | 524 | } |
| 417 | 525 | return *this; |
| 418 | 526 | } |
| 419 | 527 | |
| 420 | | // comparison operator |
| 421 | | bool operator==(const delegate_base &rhs) const |
| 422 | | { |
| 423 | | return (m_object == rhs.m_object && m_function == rhs.m_function && m_rawfunction == rhs.m_rawfunction); |
| 424 | | } |
| 425 | | |
| 426 | | // getters |
| 427 | | bool isnull() const { return (m_function == NULL); } |
| 428 | | |
| 429 | 528 | // call the function |
| 430 | 529 | _ReturnType operator()() const { return (*m_function)(m_callobject); } |
| 431 | 530 | _ReturnType operator()(_P1Type p1) const { return (*m_function)(m_callobject, p1); } |
| r18528 | r18529 | |
| 454 | 553 | { |
| 455 | 554 | typedef _ReturnType (_FunctionClass::*mfptype)(); |
| 456 | 555 | delegate_base *_this = reinterpret_cast<delegate_base *>(object); |
| 457 | | mfptype &mfp = _this->m_rawfunction.mfp<mfptype>(); |
| 556 | mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>(); |
| 458 | 557 | return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)(); |
| 459 | 558 | } |
| 460 | 559 | |
| r18528 | r18529 | |
| 463 | 562 | { |
| 464 | 563 | typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1); |
| 465 | 564 | delegate_base *_this = reinterpret_cast<delegate_base *>(object); |
| 466 | | mfptype &mfp = _this->m_rawfunction.mfp<mfptype>(); |
| 565 | mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>(); |
| 467 | 566 | return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)(p1); |
| 468 | 567 | } |
| 469 | 568 | |
| r18528 | r18529 | |
| 472 | 571 | { |
| 473 | 572 | typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1, _P2Type p2); |
| 474 | 573 | delegate_base *_this = reinterpret_cast<delegate_base *>(object); |
| 475 | | mfptype &mfp = _this->m_rawfunction.mfp<mfptype>(); |
| 574 | mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>(); |
| 476 | 575 | return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)(p1, p2); |
| 477 | 576 | } |
| 478 | 577 | |
| r18528 | r18529 | |
| 481 | 580 | { |
| 482 | 581 | typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1, _P2Type p2, _P3Type p3); |
| 483 | 582 | delegate_base *_this = reinterpret_cast<delegate_base *>(object); |
| 484 | | mfptype &mfp = _this->m_rawfunction.mfp<mfptype>(); |
| 583 | mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>(); |
| 485 | 584 | return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)(p1, p2, p3); |
| 486 | 585 | } |
| 487 | 586 | |
| r18528 | r18529 | |
| 490 | 589 | { |
| 491 | 590 | typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4); |
| 492 | 591 | delegate_base *_this = reinterpret_cast<delegate_base *>(object); |
| 493 | | mfptype &mfp = _this->m_rawfunction.mfp<mfptype>(); |
| 592 | mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>(); |
| 494 | 593 | return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)(p1, p2, p3, p4); |
| 495 | 594 | } |
| 496 | 595 | |
| r18528 | r18529 | |
| 499 | 598 | { |
| 500 | 599 | typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4, _P5Type p5); |
| 501 | 600 | delegate_base *_this = reinterpret_cast<delegate_base *>(object); |
| 502 | | mfptype &mfp = _this->m_rawfunction.mfp<mfptype>(); |
| 601 | mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>(); |
| 503 | 602 | return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)(p1, p2, p3, p4, p5); |
| 504 | 603 | } |
| 505 | 604 | |
| 506 | 605 | // internal state |
| 507 | 606 | generic_static_func m_function; // generic static function pointer |
| 508 | 607 | delegate_generic_class * m_callobject; // pointer to the object used for calling |
| 509 | | delegate_raw_mfp m_rawfunction; // copy of raw MFP |
| 510 | 608 | }; |
| 511 | 609 | |
| 512 | 610 | #endif |
| r18528 | r18529 | |
| 518 | 616 | |
| 519 | 617 | #if (USE_DELEGATE_TYPE == DELEGATE_TYPE_INTERNAL) |
| 520 | 618 | |
| 521 | | // a generic function pointer type and a generic member function pointer type |
| 522 | | typedef void (*delegate_generic_function)(); |
| 523 | | |
| 524 | | // struct describing the contents of a member function pointer |
| 525 | | struct delegate_internal_mfp |
| 526 | | { |
| 527 | | // default constructor |
| 528 | | delegate_internal_mfp() |
| 529 | | : m_function(0), |
| 530 | | m_this_delta(0) { } |
| 531 | | |
| 532 | | // copy constructor |
| 533 | | delegate_internal_mfp(const delegate_internal_mfp &src) |
| 534 | | : m_function(src.m_function), |
| 535 | | m_this_delta(src.m_this_delta) { } |
| 536 | | |
| 537 | | // construct from any member function pointer |
| 538 | | template<typename _FunctionPtr> |
| 539 | | delegate_internal_mfp(_FunctionPtr funcptr) |
| 540 | | { |
| 541 | | assert(sizeof(funcptr) == sizeof(*this)); |
| 542 | | *reinterpret_cast<_FunctionPtr *>(this) = funcptr; |
| 543 | | } |
| 544 | | |
| 545 | | // assignment operator |
| 546 | | delegate_internal_mfp &operator=(const delegate_internal_mfp &src) |
| 547 | | { |
| 548 | | if (this != &src) |
| 549 | | { |
| 550 | | m_function = src.m_function; |
| 551 | | m_this_delta = src.m_this_delta; |
| 552 | | } |
| 553 | | return *this; |
| 554 | | } |
| 555 | | |
| 556 | | // comparison operator |
| 557 | | bool operator==(const delegate_internal_mfp &rhs) const |
| 558 | | { |
| 559 | | return (m_function == rhs.m_function && m_this_delta == rhs.m_this_delta); |
| 560 | | } |
| 561 | | |
| 562 | | // extract the generic function and adjust the object pointer |
| 563 | | delegate_generic_function convert_to_generic(delegate_generic_class *&object) const; |
| 564 | | |
| 565 | | // actual state |
| 566 | | FPTR m_function; // first item can be one of two things: |
| 567 | | // if even, it's a pointer to the function |
| 568 | | // if odd, it's the byte offset into the vtable |
| 569 | | int m_this_delta; // delta to apply to the 'this' pointer |
| 570 | | }; |
| 571 | | |
| 572 | | |
| 573 | 619 | // ======================> delegate_base |
| 574 | 620 | |
| 575 | 621 | template<typename _ReturnType, typename _P1Type = _noparam, typename _P2Type = _noparam, typename _P3Type = _noparam, typename _P4Type = _noparam, typename _P5Type = _noparam> |
| r18528 | r18529 | |
| 593 | 639 | // copy constructor |
| 594 | 640 | delegate_base(const delegate_base &src) |
| 595 | 641 | : delegate_common_base(src), |
| 596 | | m_function(src.m_function), |
| 597 | | m_rawfunction(src.m_rawfunction) { } |
| 642 | m_function(src.m_function) { } |
| 598 | 643 | |
| 599 | 644 | // copy constructor with late bind |
| 600 | 645 | delegate_base(const delegate_base &src, delegate_late_bind &object) |
| 601 | 646 | : delegate_common_base(src), |
| 602 | | m_function(src.m_function), |
| 603 | | m_rawfunction(src.m_rawfunction) |
| 647 | m_function(src.m_function) |
| 604 | 648 | { |
| 605 | 649 | late_bind(object); |
| 606 | 650 | } |
| r18528 | r18529 | |
| 608 | 652 | // construct from member function with object pointer |
| 609 | 653 | template<class _FunctionClass> |
| 610 | 654 | delegate_base(typename traits<_FunctionClass>::member_func_type funcptr, const char *name, _FunctionClass *object) |
| 611 | | : delegate_common_base(name, &late_bind_helper<_FunctionClass>), |
| 612 | | m_function(NULL), |
| 613 | | m_rawfunction(funcptr) |
| 655 | : delegate_common_base(name, &late_bind_helper<_FunctionClass>, funcptr), |
| 656 | m_function(NULL) |
| 614 | 657 | { |
| 615 | 658 | bind(reinterpret_cast<delegate_generic_class *>(object)); |
| 616 | 659 | } |
| r18528 | r18529 | |
| 618 | 661 | // construct from static function with object pointer |
| 619 | 662 | template<class _FunctionClass> |
| 620 | 663 | delegate_base(typename traits<_FunctionClass>::static_func_type funcptr, const char *name, _FunctionClass *object) |
| 621 | | : delegate_common_base(name, &late_bind_helper<_FunctionClass>), |
| 664 | : delegate_common_base(name, &late_bind_helper<_FunctionClass>, reinterpret_cast<delegate_generic_function>(funcptr)), |
| 622 | 665 | m_function(reinterpret_cast<generic_static_func>(funcptr)) |
| 623 | 666 | { |
| 624 | 667 | bind(reinterpret_cast<delegate_generic_class *>(object)); |
| r18528 | r18529 | |
| 627 | 670 | // construct from static reference function with object pointer |
| 628 | 671 | template<class _FunctionClass> |
| 629 | 672 | delegate_base(typename traits<_FunctionClass>::static_ref_func_type funcptr, const char *name, _FunctionClass *object) |
| 630 | | : delegate_common_base(name, &late_bind_helper<_FunctionClass>), |
| 673 | : delegate_common_base(name, &late_bind_helper<_FunctionClass>, reinterpret_cast<delegate_generic_function>(funcptr)), |
| 631 | 674 | m_function(reinterpret_cast<generic_static_func>(funcptr)) |
| 632 | 675 | { |
| 633 | 676 | bind(reinterpret_cast<delegate_generic_class *>(object)); |
| r18528 | r18529 | |
| 638 | 681 | { |
| 639 | 682 | if (this != &src) |
| 640 | 683 | { |
| 641 | | m_name = src.m_name; |
| 642 | | m_object = src.m_object; |
| 684 | delegate_common_base::copy(src); |
| 643 | 685 | m_function = src.m_function; |
| 644 | | m_rawfunction = src.m_rawfunction; |
| 645 | | m_latebinder = src.m_latebinder; |
| 646 | 686 | } |
| 647 | 687 | return *this; |
| 648 | 688 | } |
| 649 | 689 | |
| 650 | | // comparison operator |
| 651 | | bool operator==(const delegate_base &rhs) const |
| 652 | | { |
| 653 | | return (m_object == rhs.m_object && m_function == rhs.m_function && m_rawfunction == rhs.m_rawfunction); |
| 654 | | } |
| 655 | | |
| 656 | | // getters |
| 657 | | bool isnull() const { return (m_function == NULL && m_rawfunction.m_function == 0); } |
| 658 | | |
| 659 | 690 | // call the function |
| 660 | 691 | _ReturnType operator()() const { return (*m_function)(m_object); } |
| 661 | 692 | _ReturnType operator()(_P1Type p1) const { return (*m_function)(m_object, p1); } |
| r18528 | r18529 | |
| 672 | 703 | void bind(delegate_generic_class *object) |
| 673 | 704 | { |
| 674 | 705 | m_object = object; |
| 675 | | if (m_object != NULL && m_rawfunction.m_function != 0) |
| 676 | | m_function = reinterpret_cast<generic_static_func>(m_rawfunction.convert_to_generic(m_object)); |
| 706 | if (m_object != NULL && is_mfp()) |
| 707 | m_function = reinterpret_cast<generic_static_func>(m_raw_mfp.convert_to_generic(m_object)); |
| 677 | 708 | } |
| 678 | 709 | |
| 679 | 710 | // internal state |
| 680 | 711 | generic_static_func m_function; // generic static function pointer |
| 681 | | delegate_internal_mfp m_rawfunction; // raw member function definition |
| 682 | 712 | }; |
| 683 | 713 | |
| 684 | 714 | #endif |