Function to delegate conversion
Kirk McDonald
kirklin.mcdonald at gmail.com
Mon Jun 26 14:39:45 PDT 2006
BCS wrote:
> Kirk McDonald wrote:
>
>>
>> The following dirty, dirty hack /appears/ to work, at least in this
>> trivial case:
>>
>> import std.stdio;
>>
>> struct DG {
>> Object instance;
I think you mean:
- void function() fn;
+ void* fn;
>> }
>>
>> union U {
>> DG fake_dg;
>> void delegate() real_dg;
>> }
>>
>> class A {
>> void foo() { writefln("A.foo()"); }
>> }
>>
>> void main() {
>> A a = new A;
>> void function() fn = &A.foo;
>>
>> U u;
>> u.fake_dg.instance = a;
>
>
> - u.fake_dg.fn = fn;
> + u.fake_dg.fn = cast(void*)fn;
>
>>
>> // Call it
>> u.real_dg();
>> }
>>
>
> That should also work and won't care about types. But it is still
> really, really dirty. But it's more portable that the last solution I
> saw, That one used ASM hacking.
But yes, that is a good idea. Templatizing real_dg, however, is going to
be a royal pain in the ass, but possible. With Daniel Keep's ftype
module, we can get something like:
struct DG {
Object instance;
void* fn;
}
template dg_unionT(Fn) {
const uint ARGS = NumberOfArgs!(Fn);
alias ReturnType!(Fn) RetType;
union U {
DG fake_dg;
static if (ARGS == 0) {
RetType delegate() real_dg;
} else static if (ARGS == 1) {
RetType delegate(ArgType!(Fn, 1)) real_dg;
} else statif if (ARGS == 2) {
RetType delegate(ArgType!(Fn, 1), ArgType!(Fn, 2)) real_dg;
} // and so on...
}
}
template U(Fn) {
alias dg_unionT!(Fn).U U;
}
void main() {
A a = new A;
auto fn = &A.foo;
U!(typeof(fn)) u;
u.fake_dg.instance = a;
u.fake_dg.fn = cast(void*)fn;
u.real_dg();
}
Also not pretty, but it should work, insofar as this whole trick works.
-Kirk McDonald
More information about the Digitalmars-d
mailing list