Previous 199869 Revisions Next

r18562 Tuesday 16th October, 2012 at 20:33:42 UTC by Aaron Giles
And a final cleanup/merging of delegate classes.
[src/emu]delegate.c delegate.h

trunk/src/emu/delegate.c
r18561r18562
4242
4343
4444//**************************************************************************
45//  GLOBAL VARIABLES
46//**************************************************************************
47
48#if (USE_DELEGATE_TYPE == DELEGATE_TYPE_COMPATIBLE)
49
50delegate_mfp::raw_mfp_data delegate_mfp::s_null_mfp = { 0 };
51
52#endif
53
54
55
56//**************************************************************************
4557//  INTERNAL DELEGATE HELPERS
4658//**************************************************************************
4759
trunk/src/emu/delegate.h
r18561r18562
248248// in a static buffer, and can effectively recast itself back for later use;
249249// it hides some of the gross details involved in copying artibtrary member
250250// function pointers around
251struct delegate_mfp
251class delegate_mfp
252252{
253public:
253254   // 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) { }
255259   
256260   // copy constructor
257261   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) { }
259265
260266   // 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>))
263272   {
264273      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;
267275   }
268276
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)
271287   {
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);
275291   }
276292
277   // comparison operator
278   bool operator==(const delegate_mfp &rhs) const
293private:
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)
279353   {
280      return (memcmp(&m_rawdata, &rhs.m_rawdata, sizeof(m_rawdata)) == 0);
354      return reinterpret_cast<delegate_generic_function>(funcptr);
281355   }
282356
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
285359   {
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   };
291363
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
302369};
303370
304371#elif (USE_DELEGATE_TYPE == DELEGATE_TYPE_INTERNAL)
r18561r18562
306373// ======================> delegate_mfp
307374
308375// struct describing the contents of a member function pointer
309struct delegate_mfp
376class delegate_mfp
310377{
378public:
311379   // default constructor
312380   delegate_mfp()
313381      : m_function(0),
r18561r18562
319387        m_this_delta(src.m_this_delta) { }
320388
321389   // 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)
324392   {
325393      assert(sizeof(mfp) == sizeof(*this));
326      *reinterpret_cast<_FunctionPtr *>(this) = mfp;
394      *reinterpret_cast<_MemberFunctionType *>(this) = mfp;
327395   }
328396
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); }
339400
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)
342407   {
343      return (m_function == rhs.m_function && m_this_delta == rhs.m_this_delta);
408      funcptr = reinterpret_cast<_FunctionType>(convert_to_generic(object));
344409   }
345   
346   // isnull checker
347   bool isnull() const { return (m_function == 0); }
348410
411private:
349412   // extract the generic function and adjust the object pointer
350413   delegate_generic_function convert_to_generic(delegate_generic_class *&object) const;
351414
r18561r18562
359422#endif
360423
361424
425
362426//**************************************************************************
363427//  COMMON DELEGATE BASE CLASS
364428//**************************************************************************
365429
366// ======================> delegate_common_base
367
368// common non-templatized base class
369class delegate_common_base
370{
371protected:
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   
407public:
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
422protected:
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
504430// ======================> delegate_base
505431
506// general delegate class template supporting up to 4 parameters
432// general delegate class template supporting up to 5 parameters
507433template<typename _ReturnType, typename _P1Type = _noparam, typename _P2Type = _noparam, typename _P3Type = _noparam, typename _P4Type = _noparam, typename _P5Type = _noparam>
508class delegate_base : public delegate_common_base
434class delegate_base
509435{
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
516436public:
517437   // define our traits
518438   template<class _FunctionClass>
r18561r18562
527447   // generic constructor
528448   delegate_base()
529449      : m_function(NULL),
530        m_callobject(NULL) { }
450        m_object(NULL),
451        m_name(NULL),
452        m_latebinder(NULL),
453        m_raw_function(NULL) { }
531454
532455   // copy constructor
533456   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   }
537466
538467   // copy constructor with late bind
539468   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)
543475   {
544476      late_bind(object);
545477   }
r18561r18562
547479   // construct from member function with object pointer
548480   template<class _FunctionClass>
549481   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)
557488   {
558489      bind(reinterpret_cast<delegate_generic_class *>(object));
559490   }
r18561r18562
561492   // construct from static function with object pointer
562493   template<class _FunctionClass>
563494   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))
567500   {
568501      bind(reinterpret_cast<delegate_generic_class *>(object));
569502   }
570503
571   // construct from static reference function with object pointer
504   // construct from static reference function with object reference
572505   template<class _FunctionClass>
573506   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))
577512   {
578513      bind(reinterpret_cast<delegate_generic_class *>(object));
579514   }
r18561r18562
583518   {
584519      if (this != &src)
585520      {
586         delegate_common_base::copy(src);
587         m_callobject = copy_callobject(src);
588521         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());
589528      }
590529      return *this;
591530   }
592531
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
593538   // 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
602539   _ReturnType operator()() const { return (*m_function)(m_object); }
603540   _ReturnType operator()(_P1Type p1) const { return (*m_function)(m_object, p1); }
604541   _ReturnType operator()(_P1Type p1, _P2Type p2) const { return (*m_function)(m_object, p1, p2); }
605542   _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3) const { return (*m_function)(m_object, p1, p2, p3); }
606543   _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4) const { return (*m_function)(m_object, p1, p2, p3, p4); }
607544   _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
609545
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
610554   // late binding
611555   void late_bind(delegate_late_bind &object) { bind((*m_latebinder)(object)); }
612556
613557protected:
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
614574   // bind the actual object
615575   void bind(delegate_generic_class *object)
616576   {
617577      m_object = object;
618578     
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
625580      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);
628582   }
629583
630584   // 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
633591};
634592
635593

Previous 199869 Revisions Next


© 1997-2024 The MAME Team