SRC: Делегаты и события на VC++ 6.0 (часть 2)
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 31.10.02 16:22
Оценка: 12 (1)
Почему-то не удалось отправить все файлы одним письмом, так что здесь — только сигнатурные шаблоны V0 и R2.

V0.h
#ifndef V0_h
#define V0_h

// ********* V0 **********


/*

Шаблоны для делегатов/событий, сигнатуры которых
представляют собой void(void)

*/

template<typename PARAMS, typename BASE> class packed_caller_V0;
template<typename PARAMS> class delegate_V0_base;

class Params_V0
{
  public:

    typedef struct _Data
    {
    } _packed_data_t;

    typedef void (__stdcall *_stdcall_func_t)(void);
    typedef void (__cdecl *_cdecl_func_t)(void);
    typedef void (__fastcall *_fastcall_func_t)(void);

    static inline void func_call(_stdcall_func_t func, _packed_data_t *)
    {
      if (func) func();
    }
    static inline void func_call(_fastcall_func_t func, _packed_data_t *)
    {
      if (func) func();
    }
    static inline void func_call(_cdecl_func_t func, _packed_data_t *)
    {
      if (func) func();
    }

    typedef func_adapter_base<Params_V0, _stdcall_func_t> _stdcall_func_adapter_t;
    typedef func_adapter_base<Params_V0, _cdecl_func_t> _cdecl_func_adapter_t;
    typedef func_adapter_base<Params_V0, _fastcall_func_t> _fastcall_func_adapter_t;

    typedef packed_caller_V0<Params_V0, delegate_common<Params_V0> > _packed_caller_t;
    typedef packed_caller_V0<Params_V0, event_common<Params_V0> > _event_base_t;
    typedef delegate_V0_base<Params_V0> _dlgt_base_t;
};

template<typename HOST, typename METHOD_CALL>
class method_adapter_V0 : public method_adapter_base<HOST, Params_V0, METHOD_CALL>
{
  public:
    typedef method_adapter_base<HOST, Params_V0, METHOD_CALL> _base_t;

    method_adapter_V0(HOST *pHost, _base_t::_method_t pMethod)
      : _base_t(pHost, pMethod){}

  protected:
    virtual void packed_call(Params_V0::_packed_data_t *pParams) const
    {
      if (_host && _method) (_host ->* _method) ();
    }
    virtual void clone_only(void *p) const { new (p)method_adapter_V0(*this); }
    virtual size_t get_size(void) const { return sizeof(*this); }
}; // method_adapter_V0

template<typename HOST, typename PARAMS>
class class_method_trait_V0
{
  public:
    typedef HOST                _host_t;
    typedef PARAMS              _params_t;

    typedef void (HOST::*_method_t)(void);
    typedef void (__stdcall  HOST::*_stdcall_method_t)(void);
    typedef void (__cdecl    HOST::  *_cdecl_method_t)(void);
    typedef void (__fastcall HOST::*_fastcall_method_t)(void);

    typedef method_adapter_V0<HOST, _stdcall_method_t> _stdcall_method_adapter;
    typedef method_adapter_V0<HOST, _cdecl_method_t> _cdecl_method_adapter;
    typedef method_adapter_V0<HOST, _fastcall_method_t> _fastcall_method_adapter;
    typedef method_adapter_V0<HOST, _method_t> method_adapter;
}; // class_method_trait_V0<>

template<typename PARAMS>
class delegate_V0_base : public PARAMS::_packed_caller_t
{
  public:
    typedef delegate_V0_base _this_t;
    
    template<typename HOST>
      method_assignment<class_method_trait_V0<HOST, PARAMS>, _this_t>
                  use_method(HOST *pHost)
      {
        return method_assignment<class_method_trait_V0<HOST, PARAMS>,
                          _this_t> (this, pHost);
        ;
      }
    template<class HOST>
      inline method_assignment<class_method_trait_V0<HOST, PARAMS>, // Характеристики операции
                  _this_t> operator [] (HOST &obj)
      {
        return use_method(&obj);
      }
}; // delegate_V0_base

template<typename PARAMS, typename BASE>
class packed_caller_V0 : public BASE
{
  public:
    inline void operator ()(void) const
    {
      packed_call(NULL);
    }
}; // packed_caller_V0

// *** V0 ***

#endif /* V0_h */


R2.h
#ifndef R2_h
#define R2_h

// ********* R2 **********

/*

Шаблоны для делегатов/событий, сигнатуры которых
представляют собой type(param, param)

*/

template<typename HOST, typename PARAMS, typename METHOD_CALL>
class method_adapter_R2 : public method_adapter_base<HOST, PARAMS, METHOD_CALL>
{
  public:
    typedef method_adapter_base<HOST, PARAMS, METHOD_CALL> _base_t;

    method_adapter_R2(HOST *pHost, _base_t::_method_t pMethod)
      : _base_t(pHost, pMethod){}

  protected:
    virtual void packed_call(PARAMS::_packed_data_t *pParams) const
    {
      PARAMS::_packed_data_t *data = (PARAMS::_packed_data_t *)pParams;
      if (_host && _method)
        pParams -> res = (_host ->* _method) (data->p1, data->p2);
    }
    virtual void clone_only(void *p) const { new (p)method_adapter_R2(*this); }
    virtual size_t get_size(void) const { return sizeof(*this); }
}; // method_adapter_R2

template<typename HOST, typename PARAMS>
class class_method_trait_R2
{
  public:
    typedef HOST                _host_t;
    typedef PARAMS              _params_t;

    typedef PARAMS::res_t (HOST::*_method_t)(PARAMS::p1_t, PARAMS::p2_t);
    typedef PARAMS::res_t (__stdcall  HOST::*_stdcall_method_t)(PARAMS::p1_t, PARAMS::p2_t);
    typedef PARAMS::res_t (__cdecl    HOST::  *_cdecl_method_t)(PARAMS::p1_t, PARAMS::p2_t);
    typedef PARAMS::res_t (__fastcall HOST::*_fastcall_method_t)(PARAMS::p1_t, PARAMS::p2_t);

    typedef method_adapter_R2<HOST, PARAMS, _stdcall_method_t> _stdcall_method_adapter;
    typedef method_adapter_R2<HOST, PARAMS, _cdecl_method_t> _cdecl_method_adapter;
    typedef method_adapter_R2<HOST, PARAMS, _fastcall_method_t> _fastcall_method_adapter;
    typedef method_adapter_R2<HOST, PARAMS, _method_t> method_adapter;
}; // class_method_trait_R2<>

template<typename PARAMS>
class delegate_R2_base : public PARAMS::_packed_caller_t
{
  public:
    typedef delegate_R2_base _this_t;
    
    template<typename HOST>
      method_assignment<class_method_trait_R2<HOST, PARAMS>, _this_t>
                  use_method(HOST *pHost)
      {
        return method_assignment<class_method_trait_R2<HOST, PARAMS>,
                          _this_t> (this, pHost);
        ;
      }
    template<class HOST>
      inline method_assignment<class_method_trait_R2<HOST, PARAMS>, // Характеристики операции
                  _this_t> operator [] (HOST &obj)
      {
        return use_method(&obj);
      }
}; // delegate_R2_base

template<typename PARAMS, typename BASE>
class packed_caller_R2 : public BASE
{
  public:
    inline PARAMS::res_t operator ()(PARAMS::p1_t p1, PARAMS::p2_t p2) const
    {
      PARAMS::_packed_data_t p = { p1, p2 };
      packed_call(&p);
      return p.res;
    }
}; // packed_caller_R2


template<typename RES, typename P1, typename P2>
class params_R2
{
  public:
    typedef P1 p1_t;
    typedef P2 p2_t;
    typedef RES res_t;

    typedef struct _Data
    {
      P1 p1;
      P2 p2;
      RES res;
    } _packed_data_t;

    typedef res_t (__stdcall *_stdcall_func_t)(p1_t, p2_t);
    typedef res_t (__cdecl *_cdecl_func_t)(p1_t, p2_t);
    typedef res_t (__fastcall *_fastcall_func_t)(p1_t, p2_t);

    static inline void func_call(_stdcall_func_t func, _packed_data_t *data)
    {
      if (func) data -> res = func(data->p1, data->p2);
    }
    static inline void func_call(_fastcall_func_t func, _packed_data_t *data)
    {
      if (func) data -> res = func(data->p1, data->p2);
    }
    static inline void func_call(_cdecl_func_t func, _packed_data_t *data)
    {
      if (func) data -> res = func(data->p1, data->p2);
    }

    typedef func_adapter_base<params_R2, _stdcall_func_t> _stdcall_func_adapter_t;
    typedef func_adapter_base<params_R2, _cdecl_func_t> _cdecl_func_adapter_t;
    typedef func_adapter_base<params_R2, _fastcall_func_t> _fastcall_func_adapter_t;

    typedef packed_caller_R2<params_R2, delegate_common<params_R2> > _packed_caller_t;
    typedef packed_caller_R2<params_R2, event_common<params_R2> > _event_base_t;
    typedef delegate_R2_base<params_R2> _dlgt_base_t;
};

// *** R2 ***

#endif /* R2_h */
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.