--- gvpe/src/callback.pl 2007/12/02 00:54:52 1.10 +++ gvpe/src/callback.pl 2007/12/04 15:01:12 1.11 @@ -33,11 +33,10 @@ #define CALLBACK_H_VERSION 3 -template -struct callback_funtype_trait; +template +struct callback; -template -struct callback_get_impl; +#define callback_set(callback,obj,klass,method) callback.set (obj) EOF @@ -48,35 +47,51 @@ my $TYPEARG = join ", ", map "A$_ a$_", 1..$a; my $TYPEDEFS = join " ", map "typedef A$_ arg$_\_type;", 1..$a; my $TYPEvoid = $TYPE ? $TYPE : "void"; + my $_ARG = $ARG ? ", $ARG" : ""; my $_TYPE = $TYPE ? ", $TYPE" : ""; + my $_TYPEARG = $TYPEARG ? ", $TYPEARG" : ""; my $_TTYPE = $a ? join "", map ", typename T::arg$_\_type", 1..$a : ""; print < -class callback$a +struct callback { - struct klass; // it is vital that this is never defined + typedef R (*ptr_type)(void *self$_TYPE); - typedef R (klass::*ptr_type)($TYPE); +private: - klass *o; - R (klass::*m)($TYPE); + void *self; + ptr_type func; + +protected: + + template + struct thunktype; + + template + struct thunktype + { + typedef klass K; + }; + + template + static R thunk (void *self$_TYPEARG) + { + klass *obj = static_cast(self); + return (obj->*method) ($ARG); + } public: - template - explicit callback$a (O1 *object, R (O2::*method)($TYPE)) + template + void set (K *object) { - o = reinterpret_cast(object); - m = reinterpret_cast(method); + self = object; + func = thunk; } - // this works because a standards-compliant C++ compiler - // basically can't help it: it doesn't have the knowledge - // required to miscompile (klass is not defined anywhere - // and nothing is known about the constructor arguments) :) - R call($TYPEARG) const + R call ($TYPEARG) const { - return (o->*m) ($ARG); + return func (self$_ARG); } R operator ()($TYPEARG) const @@ -85,44 +100,11 @@ } }; -template -struct callback_funtype_trait$a -{ - static const int arity = $a; - typedef R type ($TYPEvoid); - typedef R result_type; - $TYPEDEFS -}; - -template -struct callback_funtype_trait : callback_funtype_trait$a -{ -}; - -template -struct callback_get_impl<$a, signature> -{ - typedef callback_funtype_trait T; - typedef callback$a type; -}; - EOF } print < -struct callback : callback_get_impl::arity, signature>::type -{ - typedef typename callback_get_impl::arity, signature>::type base_type; - - template - explicit callback (O object, M method) - : base_type (object, method) - { - } -}; - #endif EOF