trunk/src/emu/delegate.h
| r18561 | r18562 | |
| 248 | 248 | // in a static buffer, and can effectively recast itself back for later use; |
| 249 | 249 | // it hides some of the gross details involved in copying artibtrary member |
| 250 | 250 | // function pointers around |
| 251 | | struct delegate_mfp |
| 251 | class delegate_mfp |
| 252 | 252 | { |
| 253 | public: |
| 253 | 254 | // default constructor |
| 254 | | delegate_mfp() { memset(&m_rawdata, 0, sizeof(m_rawdata)); } |
| 255 | delegate_mfp() |
| 256 | : m_rawdata(s_null_mfp), |
| 257 | m_realobject(NULL), |
| 258 | m_stubfunction(NULL) { } |
| 255 | 259 | |
| 256 | 260 | // copy constructor |
| 257 | 261 | delegate_mfp(const delegate_mfp &src) |
| 258 | | : m_rawdata(src.m_rawdata) { } |
| 262 | : m_rawdata(src.m_rawdata), |
| 263 | m_realobject(src.m_realobject), |
| 264 | m_stubfunction(src.m_stubfunction) { } |
| 259 | 265 | |
| 260 | 266 | // construct from any member function pointer |
| 261 | | template<typename _FunctionType> |
| 262 | | delegate_mfp(_FunctionType mfp) |
| 267 | template<typename _MemberFunctionType, class _MemberFunctionClass, typename _ReturnType, typename _StaticFunctionType> |
| 268 | delegate_mfp(_MemberFunctionType mfp, _MemberFunctionClass *, _ReturnType *, _StaticFunctionType) |
| 269 | : m_rawdata(s_null_mfp), |
| 270 | m_realobject(NULL), |
| 271 | m_stubfunction(make_generic<_StaticFunctionType>(&delegate_mfp::method_stub<_MemberFunctionClass, _ReturnType>)) |
| 263 | 272 | { |
| 264 | 273 | assert(sizeof(mfp) <= sizeof(m_rawdata)); |
| 265 | | memset(&m_rawdata, 0, sizeof(m_rawdata)); |
| 266 | | *reinterpret_cast<_FunctionType *>(&m_rawdata) = mfp; |
| 274 | *reinterpret_cast<_MemberFunctionType *>(&m_rawdata) = mfp; |
| 267 | 275 | } |
| 268 | 276 | |
| 269 | | // assignment operator |
| 270 | | delegate_mfp &operator=(const delegate_mfp &src) |
| 277 | // comparison helpers |
| 278 | bool operator==(const delegate_mfp &rhs) const { return (m_rawdata == rhs.m_rawdata); } |
| 279 | bool isnull() const { return (m_rawdata == s_null_mfp); } |
| 280 | |
| 281 | // getters |
| 282 | delegate_generic_class *real_object(delegate_generic_class *original) const { return m_realobject; } |
| 283 | |
| 284 | // binding helper |
| 285 | template<typename _FunctionType> |
| 286 | void update_after_bind(_FunctionType &funcptr, delegate_generic_class *&object) |
| 271 | 287 | { |
| 272 | | if (this != &src) |
| 273 | | m_rawdata = src.m_rawdata; |
| 274 | | return *this; |
| 288 | m_realobject = object; |
| 289 | object = reinterpret_cast<delegate_generic_class *>(this); |
| 290 | funcptr = reinterpret_cast<_FunctionType>(m_stubfunction); |
| 275 | 291 | } |
| 276 | 292 | |
| 277 | | // comparison operator |
| 278 | | bool operator==(const delegate_mfp &rhs) const |
| 293 | private: |
| 294 | // helper stubs for calling encased member function pointers |
| 295 | template<class _FunctionClass, typename _ReturnType> |
| 296 | static _ReturnType method_stub(delegate_generic_class *object) |
| 297 | { |
| 298 | delegate_mfp *_this = reinterpret_cast<delegate_mfp *>(object); |
| 299 | typedef _ReturnType (_FunctionClass::*mfptype)(); |
| 300 | mfptype &mfp = *reinterpret_cast<mfptype *>(&_this->m_rawdata); |
| 301 | return (reinterpret_cast<_FunctionClass *>(_this->m_realobject)->*mfp)(); |
| 302 | } |
| 303 | |
| 304 | template<class _FunctionClass, typename _ReturnType, typename _P1Type> |
| 305 | static _ReturnType method_stub(delegate_generic_class *object, _P1Type p1) |
| 306 | { |
| 307 | delegate_mfp *_this = reinterpret_cast<delegate_mfp *>(object); |
| 308 | typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1); |
| 309 | mfptype &mfp = *reinterpret_cast<mfptype *>(&_this->m_rawdata); |
| 310 | return (reinterpret_cast<_FunctionClass *>(_this->m_realobject)->*mfp)(p1); |
| 311 | } |
| 312 | |
| 313 | template<class _FunctionClass, typename _ReturnType, typename _P1Type, typename _P2Type> |
| 314 | static _ReturnType method_stub(delegate_generic_class *object, _P1Type p1, _P2Type p2) |
| 315 | { |
| 316 | delegate_mfp *_this = reinterpret_cast<delegate_mfp *>(object); |
| 317 | typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1, _P2Type p2); |
| 318 | mfptype &mfp = *reinterpret_cast<mfptype *>(&_this->m_rawdata); |
| 319 | return (reinterpret_cast<_FunctionClass *>(_this->m_realobject)->*mfp)(p1, p2); |
| 320 | } |
| 321 | |
| 322 | template<class _FunctionClass, typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type> |
| 323 | static _ReturnType method_stub(delegate_generic_class *object, _P1Type p1, _P2Type p2, _P3Type p3) |
| 324 | { |
| 325 | delegate_mfp *_this = reinterpret_cast<delegate_mfp *>(object); |
| 326 | typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1, _P2Type p2, _P3Type p3); |
| 327 | mfptype &mfp = *reinterpret_cast<mfptype *>(&_this->m_rawdata); |
| 328 | return (reinterpret_cast<_FunctionClass *>(_this->m_realobject)->*mfp)(p1, p2, p3); |
| 329 | } |
| 330 | |
| 331 | template<class _FunctionClass, typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type> |
| 332 | static _ReturnType method_stub(delegate_generic_class *object, _P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4) |
| 333 | { |
| 334 | delegate_mfp *_this = reinterpret_cast<delegate_mfp *>(object); |
| 335 | typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4); |
| 336 | mfptype &mfp = *reinterpret_cast<mfptype *>(&_this->m_rawdata); |
| 337 | return (reinterpret_cast<_FunctionClass *>(_this->m_realobject)->*mfp)(p1, p2, p3, p4); |
| 338 | } |
| 339 | |
| 340 | template<class _FunctionClass, typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type, typename _P5Type> |
| 341 | static _ReturnType method_stub(delegate_generic_class *object, _P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4, _P5Type p5) |
| 342 | { |
| 343 | delegate_mfp *_this = reinterpret_cast<delegate_mfp *>(object); |
| 344 | typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4, _P5Type p5); |
| 345 | mfptype &mfp = *reinterpret_cast<mfptype *>(&_this->m_rawdata); |
| 346 | return (reinterpret_cast<_FunctionClass *>(_this->m_realobject)->*mfp)(p1, p2, p3, p4, p5); |
| 347 | } |
| 348 | |
| 349 | // helper to convert a function of a given type to a generic function, forcing template |
| 350 | // instantiation to match the source type |
| 351 | template <typename _SourceType> |
| 352 | delegate_generic_function make_generic(_SourceType funcptr) |
| 279 | 353 | { |
| 280 | | return (memcmp(&m_rawdata, &rhs.m_rawdata, sizeof(m_rawdata)) == 0); |
| 354 | return reinterpret_cast<delegate_generic_function>(funcptr); |
| 281 | 355 | } |
| 282 | 356 | |
| 283 | | // isnull checker |
| 284 | | bool isnull() const |
| 357 | // for MSVC maximum size is one pointer, plus 3 ints; all other implementations seem to be smaller |
| 358 | struct raw_mfp_data |
| 285 | 359 | { |
| 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 | | } |
| 360 | int data[((sizeof(void *) + 3 * sizeof(int)) + (sizeof(int) - 1)) / sizeof(int)]; |
| 361 | bool operator==(const raw_mfp_data &rhs) const { return (memcmp(data, rhs.data, sizeof(data)) == 0); } |
| 362 | }; |
| 291 | 363 | |
| 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; |
| 364 | // internal state |
| 365 | raw_mfp_data m_rawdata; // raw buffer to hold the copy of the function pointer |
| 366 | delegate_generic_class * m_realobject; // pointer to the object used for calling |
| 367 | delegate_generic_function m_stubfunction; // pointer to our matching stub function |
| 368 | static raw_mfp_data s_null_mfp; // NULL mfp |
| 302 | 369 | }; |
| 303 | 370 | |
| 304 | 371 | #elif (USE_DELEGATE_TYPE == DELEGATE_TYPE_INTERNAL) |
| r18561 | r18562 | |
| 306 | 373 | // ======================> delegate_mfp |
| 307 | 374 | |
| 308 | 375 | // struct describing the contents of a member function pointer |
| 309 | | struct delegate_mfp |
| 376 | class delegate_mfp |
| 310 | 377 | { |
| 378 | public: |
| 311 | 379 | // default constructor |
| 312 | 380 | delegate_mfp() |
| 313 | 381 | : m_function(0), |
| r18561 | r18562 | |
| 319 | 387 | m_this_delta(src.m_this_delta) { } |
| 320 | 388 | |
| 321 | 389 | // construct from any member function pointer |
| 322 | | template<typename _FunctionPtr> |
| 323 | | delegate_mfp(_FunctionPtr mfp) |
| 390 | template<typename _MemberFunctionType, class _MemberFunctionClass, typename _ReturnType, typename _StaticFunctionType> |
| 391 | delegate_mfp(_MemberFunctionType mfp, _MemberFunctionClass *, _ReturnType *, _StaticFunctionType) |
| 324 | 392 | { |
| 325 | 393 | assert(sizeof(mfp) == sizeof(*this)); |
| 326 | | *reinterpret_cast<_FunctionPtr *>(this) = mfp; |
| 394 | *reinterpret_cast<_MemberFunctionType *>(this) = mfp; |
| 327 | 395 | } |
| 328 | 396 | |
| 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 | | } |
| 397 | // comparison helpers |
| 398 | bool operator==(const delegate_mfp &rhs) const { return (m_function == rhs.m_function && m_this_delta == rhs.m_this_delta); } |
| 399 | bool isnull() const { return (m_function == 0); } |
| 339 | 400 | |
| 340 | | // comparison operator |
| 341 | | bool operator==(const delegate_mfp &rhs) const |
| 401 | // getters |
| 402 | delegate_generic_class *real_object(delegate_generic_class *original) const { return original; } |
| 403 | |
| 404 | // binding helper |
| 405 | template<typename _FunctionType> |
| 406 | void update_after_bind(_FunctionType &funcptr, delegate_generic_class *&object) |
| 342 | 407 | { |
| 343 | | return (m_function == rhs.m_function && m_this_delta == rhs.m_this_delta); |
| 408 | funcptr = reinterpret_cast<_FunctionType>(convert_to_generic(object)); |
| 344 | 409 | } |
| 345 | | |
| 346 | | // isnull checker |
| 347 | | bool isnull() const { return (m_function == 0); } |
| 348 | 410 | |
| 411 | private: |
| 349 | 412 | // extract the generic function and adjust the object pointer |
| 350 | 413 | delegate_generic_function convert_to_generic(delegate_generic_class *&object) const; |
| 351 | 414 | |
| r18561 | r18562 | |
| 359 | 422 | #endif |
| 360 | 423 | |
| 361 | 424 | |
| 425 | |
| 362 | 426 | //************************************************************************** |
| 363 | 427 | // COMMON DELEGATE BASE CLASS |
| 364 | 428 | //************************************************************************** |
| 365 | 429 | |
| 366 | | // ======================> delegate_common_base |
| 367 | | |
| 368 | | // common non-templatized base class |
| 369 | | class delegate_common_base |
| 370 | | { |
| 371 | | protected: |
| 372 | | typedef delegate_generic_class *(*late_bind_func)(delegate_late_bind &object); |
| 373 | | |
| 374 | | // construction |
| 375 | | delegate_common_base(const char *name = NULL, late_bind_func latebinder = NULL, delegate_generic_function funcptr = NULL) |
| 376 | | : m_name(name), |
| 377 | | m_object(NULL), |
| 378 | | m_latebinder(latebinder), |
| 379 | | m_raw_function(funcptr) { } |
| 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 |
| 390 | | delegate_common_base(const delegate_common_base &src) |
| 391 | | : m_name(src.m_name), |
| 392 | | m_object(src.m_object), |
| 393 | | m_latebinder(src.m_latebinder), |
| 394 | | m_raw_function(src.m_raw_function), |
| 395 | | m_raw_mfp(src.m_raw_mfp) { } |
| 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 | | |
| 407 | | public: |
| 408 | | // getters |
| 409 | | bool has_object() const { return (m_object != NULL); } |
| 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(); } |
| 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 | | |
| 422 | | protected: |
| 423 | | // late binding helper |
| 424 | | template<class _FunctionClass> |
| 425 | | static delegate_generic_class *late_bind_helper(delegate_late_bind &object) |
| 426 | | { |
| 427 | | _FunctionClass *result = dynamic_cast<_FunctionClass *>(&object); |
| 428 | | if (result == NULL) |
| 429 | | throw binding_type_exception(typeid(_FunctionClass), typeid(object)); |
| 430 | | return reinterpret_cast<delegate_generic_class *>(result); |
| 431 | | } |
| 432 | | |
| 433 | | #if (USE_DELEGATE_TYPE == DELEGATE_TYPE_COMPATIBLE) |
| 434 | | // helper stub that calls the member function; we need one for each parameter count |
| 435 | | template<class _FunctionClass, typename _ReturnType> |
| 436 | | static _ReturnType method_stub(delegate_generic_class *object) |
| 437 | | { |
| 438 | | typedef _ReturnType (_FunctionClass::*mfptype)(); |
| 439 | | delegate_common_base *_this = reinterpret_cast<delegate_common_base *>(object); |
| 440 | | mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>(); |
| 441 | | return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)(); |
| 442 | | } |
| 443 | | |
| 444 | | template<class _FunctionClass, typename _ReturnType, typename _P1Type> |
| 445 | | static _ReturnType method_stub(delegate_generic_class *object, _P1Type p1) |
| 446 | | { |
| 447 | | typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1); |
| 448 | | delegate_common_base *_this = reinterpret_cast<delegate_common_base *>(object); |
| 449 | | mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>(); |
| 450 | | return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)(p1); |
| 451 | | } |
| 452 | | |
| 453 | | template<class _FunctionClass, typename _ReturnType, typename _P1Type, typename _P2Type> |
| 454 | | static _ReturnType method_stub(delegate_generic_class *object, _P1Type p1, _P2Type p2) |
| 455 | | { |
| 456 | | typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1, _P2Type p2); |
| 457 | | delegate_common_base *_this = reinterpret_cast<delegate_common_base *>(object); |
| 458 | | mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>(); |
| 459 | | return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)(p1, p2); |
| 460 | | } |
| 461 | | |
| 462 | | template<class _FunctionClass, typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type> |
| 463 | | static _ReturnType method_stub(delegate_generic_class *object, _P1Type p1, _P2Type p2, _P3Type p3) |
| 464 | | { |
| 465 | | typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1, _P2Type p2, _P3Type p3); |
| 466 | | delegate_common_base *_this = reinterpret_cast<delegate_common_base *>(object); |
| 467 | | mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>(); |
| 468 | | return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)(p1, p2, p3); |
| 469 | | } |
| 470 | | |
| 471 | | template<class _FunctionClass, typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type> |
| 472 | | static _ReturnType method_stub(delegate_generic_class *object, _P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4) |
| 473 | | { |
| 474 | | typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4); |
| 475 | | delegate_common_base *_this = reinterpret_cast<delegate_common_base *>(object); |
| 476 | | mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>(); |
| 477 | | return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)(p1, p2, p3, p4); |
| 478 | | } |
| 479 | | |
| 480 | | template<class _FunctionClass, typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type, typename _P5Type> |
| 481 | | static _ReturnType method_stub(delegate_generic_class *object, _P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4, _P5Type p5) |
| 482 | | { |
| 483 | | typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4, _P5Type p5); |
| 484 | | delegate_common_base *_this = reinterpret_cast<delegate_common_base *>(object); |
| 485 | | mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>(); |
| 486 | | return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)(p1, p2, p3, p4, p5); |
| 487 | | } |
| 488 | | #endif |
| 489 | | |
| 490 | | // internal state |
| 491 | | const char * m_name; // name string |
| 492 | | delegate_generic_class * m_object; // pointer to the post-cast object |
| 493 | | late_bind_func m_latebinder; // late binding helper |
| 494 | | delegate_generic_function m_raw_function; // raw static function pointer |
| 495 | | delegate_mfp m_raw_mfp; // raw member function pointer |
| 496 | | }; |
| 497 | | |
| 498 | | |
| 499 | | |
| 500 | | //************************************************************************** |
| 501 | | // TEMPLATIZED DELEGATE BASE |
| 502 | | //************************************************************************** |
| 503 | | |
| 504 | 430 | // ======================> delegate_base |
| 505 | 431 | |
| 506 | | // general delegate class template supporting up to 4 parameters |
| 432 | // general delegate class template supporting up to 5 parameters |
| 507 | 433 | template<typename _ReturnType, typename _P1Type = _noparam, typename _P2Type = _noparam, typename _P3Type = _noparam, typename _P4Type = _noparam, typename _P5Type = _noparam> |
| 508 | | class delegate_base : public delegate_common_base |
| 434 | class delegate_base |
| 509 | 435 | { |
| 510 | | #if (USE_DELEGATE_TYPE == DELEGATE_TYPE_COMPATIBLE) |
| 511 | | delegate_generic_class *copy_callobject(const delegate_base &src) { return src.is_mfp() ? reinterpret_cast<delegate_generic_class *>(this) : src.m_object; } |
| 512 | | #else |
| 513 | | delegate_generic_class *copy_callobject(const delegate_base &src) { return src.m_callobject; } |
| 514 | | #endif |
| 515 | | |
| 516 | 436 | public: |
| 517 | 437 | // define our traits |
| 518 | 438 | template<class _FunctionClass> |
| r18561 | r18562 | |
| 527 | 447 | // generic constructor |
| 528 | 448 | delegate_base() |
| 529 | 449 | : m_function(NULL), |
| 530 | | m_callobject(NULL) { } |
| 450 | m_object(NULL), |
| 451 | m_name(NULL), |
| 452 | m_latebinder(NULL), |
| 453 | m_raw_function(NULL) { } |
| 531 | 454 | |
| 532 | 455 | // copy constructor |
| 533 | 456 | delegate_base(const delegate_base &src) |
| 534 | | : delegate_common_base(src), |
| 535 | | m_function(src.m_function), |
| 536 | | m_callobject(copy_callobject(src)) { } |
| 457 | : m_function(src.m_function), |
| 458 | m_object(NULL), |
| 459 | m_name(src.m_name), |
| 460 | m_latebinder(src.m_latebinder), |
| 461 | m_raw_function(src.m_raw_function), |
| 462 | m_raw_mfp(src.m_raw_mfp) |
| 463 | { |
| 464 | bind(src.object()); |
| 465 | } |
| 537 | 466 | |
| 538 | 467 | // copy constructor with late bind |
| 539 | 468 | delegate_base(const delegate_base &src, delegate_late_bind &object) |
| 540 | | : delegate_common_base(src), |
| 541 | | m_function(src.m_function), |
| 542 | | m_callobject(copy_callobject(src)) |
| 469 | : m_function(src.m_function), |
| 470 | m_object(NULL), |
| 471 | m_name(src.m_name), |
| 472 | m_latebinder(src.m_latebinder), |
| 473 | m_raw_function(src.m_raw_function), |
| 474 | m_raw_mfp(src.m_raw_mfp) |
| 543 | 475 | { |
| 544 | 476 | late_bind(object); |
| 545 | 477 | } |
| r18561 | r18562 | |
| 547 | 479 | // construct from member function with object pointer |
| 548 | 480 | template<class _FunctionClass> |
| 549 | 481 | delegate_base(typename traits<_FunctionClass>::member_func_type funcptr, const char *name, _FunctionClass *object) |
| 550 | | : delegate_common_base(name, &late_bind_helper<_FunctionClass>, funcptr), |
| 551 | | #if (USE_DELEGATE_TYPE == DELEGATE_TYPE_COMPATIBLE) |
| 552 | | m_function(&delegate_base::method_stub<_FunctionClass, _ReturnType>), |
| 553 | | m_callobject(reinterpret_cast<delegate_generic_class *>(this)) |
| 554 | | #else |
| 555 | | m_function(NULL) |
| 556 | | #endif |
| 482 | : m_function(NULL), |
| 483 | m_object(NULL), |
| 484 | m_name(name), |
| 485 | m_latebinder(&late_bind_helper<_FunctionClass>), |
| 486 | m_raw_function(NULL), |
| 487 | m_raw_mfp(funcptr, object, (_ReturnType *)0, (generic_static_func)0) |
| 557 | 488 | { |
| 558 | 489 | bind(reinterpret_cast<delegate_generic_class *>(object)); |
| 559 | 490 | } |
| r18561 | r18562 | |
| 561 | 492 | // construct from static function with object pointer |
| 562 | 493 | template<class _FunctionClass> |
| 563 | 494 | delegate_base(typename traits<_FunctionClass>::static_func_type funcptr, const char *name, _FunctionClass *object) |
| 564 | | : delegate_common_base(name, &late_bind_helper<_FunctionClass>, reinterpret_cast<delegate_generic_function>(funcptr)), |
| 565 | | m_function(reinterpret_cast<generic_static_func>(funcptr)), |
| 566 | | m_callobject(NULL) |
| 495 | : m_function(reinterpret_cast<generic_static_func>(funcptr)), |
| 496 | m_object(NULL), |
| 497 | m_name(name), |
| 498 | m_latebinder(&late_bind_helper<_FunctionClass>), |
| 499 | m_raw_function(reinterpret_cast<generic_static_func>(funcptr)) |
| 567 | 500 | { |
| 568 | 501 | bind(reinterpret_cast<delegate_generic_class *>(object)); |
| 569 | 502 | } |
| 570 | 503 | |
| 571 | | // construct from static reference function with object pointer |
| 504 | // construct from static reference function with object reference |
| 572 | 505 | template<class _FunctionClass> |
| 573 | 506 | delegate_base(typename traits<_FunctionClass>::static_ref_func_type funcptr, const char *name, _FunctionClass *object) |
| 574 | | : delegate_common_base(name, &late_bind_helper<_FunctionClass>, reinterpret_cast<delegate_generic_function>(funcptr)), |
| 575 | | m_function(reinterpret_cast<generic_static_func>(funcptr)), |
| 576 | | m_callobject(NULL) |
| 507 | : m_function(reinterpret_cast<generic_static_func>(funcptr)), |
| 508 | m_object(NULL), |
| 509 | m_name(name), |
| 510 | m_latebinder(&late_bind_helper<_FunctionClass>), |
| 511 | m_raw_function(reinterpret_cast<generic_static_func>(funcptr)) |
| 577 | 512 | { |
| 578 | 513 | bind(reinterpret_cast<delegate_generic_class *>(object)); |
| 579 | 514 | } |
| r18561 | r18562 | |
| 583 | 518 | { |
| 584 | 519 | if (this != &src) |
| 585 | 520 | { |
| 586 | | delegate_common_base::copy(src); |
| 587 | | m_callobject = copy_callobject(src); |
| 588 | 521 | m_function = src.m_function; |
| 522 | m_object = NULL; |
| 523 | m_name = src.m_name; |
| 524 | m_latebinder = src.m_latebinder; |
| 525 | m_raw_function = src.m_raw_function; |
| 526 | m_raw_mfp = src.m_raw_mfp; |
| 527 | bind(src.object()); |
| 589 | 528 | } |
| 590 | 529 | return *this; |
| 591 | 530 | } |
| 592 | 531 | |
| 532 | // comparison helper |
| 533 | bool operator==(const delegate_base &rhs) const |
| 534 | { |
| 535 | return (m_raw_function == rhs.m_raw_function && object() == rhs.object() && m_raw_mfp == rhs.m_raw_mfp); |
| 536 | } |
| 537 | |
| 593 | 538 | // call the function |
| 594 | | #if (USE_DELEGATE_TYPE == DELEGATE_TYPE_COMPATIBLE) |
| 595 | | _ReturnType operator()() const { return (*m_function)(m_callobject); } |
| 596 | | _ReturnType operator()(_P1Type p1) const { return (*m_function)(m_callobject, p1); } |
| 597 | | _ReturnType operator()(_P1Type p1, _P2Type p2) const { return (*m_function)(m_callobject, p1, p2); } |
| 598 | | _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3) const { return (*m_function)(m_callobject, p1, p2, p3); } |
| 599 | | _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4) const { return (*m_function)(m_callobject, p1, p2, p3, p4); } |
| 600 | | _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4, _P5Type p5) const { return (*m_function)(m_callobject, p1, p2, p3, p4, p5); } |
| 601 | | #else |
| 602 | 539 | _ReturnType operator()() const { return (*m_function)(m_object); } |
| 603 | 540 | _ReturnType operator()(_P1Type p1) const { return (*m_function)(m_object, p1); } |
| 604 | 541 | _ReturnType operator()(_P1Type p1, _P2Type p2) const { return (*m_function)(m_object, p1, p2); } |
| 605 | 542 | _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3) const { return (*m_function)(m_object, p1, p2, p3); } |
| 606 | 543 | _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4) const { return (*m_function)(m_object, p1, p2, p3, p4); } |
| 607 | 544 | _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4, _P5Type p5) const { return (*m_function)(m_object, p1, p2, p3, p4, p5); } |
| 608 | | #endif |
| 609 | 545 | |
| 546 | // getters |
| 547 | bool has_object() const { return (object() != NULL); } |
| 548 | const char *name() const { return m_name; } |
| 549 | |
| 550 | // helpers |
| 551 | bool isnull() const { return (m_raw_function == NULL && m_raw_mfp.isnull()); } |
| 552 | bool is_mfp() const { return !m_raw_mfp.isnull(); } |
| 553 | |
| 610 | 554 | // late binding |
| 611 | 555 | void late_bind(delegate_late_bind &object) { bind((*m_latebinder)(object)); } |
| 612 | 556 | |
| 613 | 557 | protected: |
| 558 | // return the actual object (not the one we use for calling) |
| 559 | delegate_generic_class *object() const { return is_mfp() ? m_raw_mfp.real_object(m_object) : m_object; } |
| 560 | |
| 561 | // late binding function |
| 562 | typedef delegate_generic_class *(*late_bind_func)(delegate_late_bind &object); |
| 563 | |
| 564 | // late binding helper |
| 565 | template<class _FunctionClass> |
| 566 | static delegate_generic_class *late_bind_helper(delegate_late_bind &object) |
| 567 | { |
| 568 | _FunctionClass *result = dynamic_cast<_FunctionClass *>(&object); |
| 569 | if (result == NULL) |
| 570 | throw binding_type_exception(typeid(_FunctionClass), typeid(object)); |
| 571 | return reinterpret_cast<delegate_generic_class *>(result); |
| 572 | } |
| 573 | |
| 614 | 574 | // bind the actual object |
| 615 | 575 | void bind(delegate_generic_class *object) |
| 616 | 576 | { |
| 617 | 577 | m_object = object; |
| 618 | 578 | |
| 619 | | // update callobject to match, unless it is pointing to ourself |
| 620 | | if (m_callobject != reinterpret_cast<delegate_generic_class *>(this)) |
| 621 | | m_callobject = m_object; |
| 622 | | |
| 623 | | #if (USE_DELEGATE_TYPE != DELEGATE_TYPE_COMPATIBLE) |
| 624 | | // update the function |
| 579 | // if we're wrapping a member function pointer, handle special stuff |
| 625 | 580 | if (m_object != NULL && is_mfp()) |
| 626 | | m_function = reinterpret_cast<generic_static_func>(m_raw_mfp.convert_to_generic(m_object)); |
| 627 | | #endif |
| 581 | m_raw_mfp.update_after_bind(m_function, m_object); |
| 628 | 582 | } |
| 629 | 583 | |
| 630 | 584 | // internal state |
| 631 | | generic_static_func m_function; // generic static function pointer |
| 632 | | delegate_generic_class * m_callobject; // pointer to the object used for calling |
| 585 | generic_static_func m_function; // resolved static function pointer |
| 586 | delegate_generic_class * m_object; // resolved object to the post-cast object |
| 587 | const char * m_name; // name string |
| 588 | late_bind_func m_latebinder; // late binding helper |
| 589 | generic_static_func m_raw_function; // raw static function pointer |
| 590 | delegate_mfp m_raw_mfp; // raw member function pointer |
| 633 | 591 | }; |
| 634 | 592 | |
| 635 | 593 | |