digitalmars.D - easily convert any method/function to a delegate
- Daniel Korsgaard <d__s__k hotmail.com> Jul 18 2007
- Robert Fraser <fraserofthenight gmail.com> Jul 18 2007
- BCS <BCS pathlink.com> Jul 18 2007
- Daniel Korsgaard <d__s__k hotmail.com> Jul 18 2007
- BCS <BCS pathlink.com> Jul 18 2007
- Daniel Korsgaard <d__s__k hotmail.com> Jul 18 2007
two simple function templates that together will enable you to
mindlessly use delegates everywhere.
Whee first post on this NG :D
.. hope you like it..
-------------------
import std.stdio;
void main()
{
void delegate() ptr;
void dg()
{
writefln("DELEGATE");
}
ptr = to_delegate(&dg);
ptr();
ptr = to_delegate(&fp);
ptr();
}
void fp()
{
writefln("FUNCTION");
}
/// two functions that will convert any
R delegate(P) to_delegate(R, P...)(R delegate(P) dg)
{
// insanely advanced operation!
return dg;
}
/// ditto
R delegate(P) to_delegate(R, P...)(R function(P) fp)
{
R delegate(P) dg;
dg.funcptr = fp;
dg.ptr = null;
return dg;
}
/+
Output:
DELEGATE
FUNCTION
+/
Jul 18 2007
Thanks! I'm already using something similar, but this should really become a language extension (FPs implicitly converted to delegates). Daniel Korsgaard Wrote:two simple function templates that together will enable you to mindlessly use delegates everywhere. Whee first post on this NG :D .. hope you like it.. ------------------- import std.stdio; void main() { void delegate() ptr; void dg() { writefln("DELEGATE"); } ptr = to_delegate(&dg); ptr(); ptr = to_delegate(&fp); ptr(); } void fp() { writefln("FUNCTION"); } /// two functions that will convert any R delegate(P) to_delegate(R, P...)(R delegate(P) dg) { // insanely advanced operation! return dg; } /// ditto R delegate(P) to_delegate(R, P...)(R function(P) fp) { R delegate(P) dg; dg.funcptr = fp; dg.ptr = null; return dg; } /+ Output: DELEGATE FUNCTION +/
Jul 18 2007
Daniel Korsgaard wrote:two simple function templates that together will enable you to mindlessly use delegates everywhere. Whee first post on this NG :D .. hope you like it.. -------------------
/// two functions that will convert any R delegate(P) to_delegate(R, P...)(R delegate(P) dg) { // insanely advanced operation! return dg; } /// ditto R delegate(P) to_delegate(R, P...)(R function(P) fp) { R delegate(P) dg; dg.funcptr = fp; dg.ptr = null; return dg; }
IIRC that doesn't (quite) work because some functions pass an arg in the same place as methods pass "this" However IIRC you /can/ pass the function pointer as the delegate ptr and then have the delegate code convert it back to the correct type and call it. R delegate(P) to_delegate(R, P...)(R function(P) fp) { auto dg = delegate R(P p) {return (cast(R function(P))(cast(void*)this))(p);} dg.ptr = cast(void*)fp; return dg; }
Jul 18 2007
BCS wrote:Daniel Korsgaard wrote:two simple function templates that together will enable you to mindlessly use delegates everywhere. Whee first post on this NG :D .. hope you like it.. -------------------
/// two functions that will convert any R delegate(P) to_delegate(R, P...)(R delegate(P) dg) { // insanely advanced operation! return dg; } /// ditto R delegate(P) to_delegate(R, P...)(R function(P) fp) { R delegate(P) dg; dg.funcptr = fp; dg.ptr = null; return dg; }
IIRC that doesn't (quite) work because some functions pass an arg in the same place as methods pass "this"
Bummer :(However IIRC you /can/ pass the function pointer as the delegate ptr and then have the delegate code convert it back to the correct type and call it.
Aye ?!R delegate(P) to_delegate(R, P...)(R function(P) fp) { auto dg = delegate R(P p) {return (cast(R function(P))(cast(void*)this))(p);} dg.ptr = cast(void*)fp; return dg; }
Err.. where do you get that 'this' from? Anyways, my idea was to cut of the additional call. But if it really have to be there, this is a lot cleaner: R delegate(P) to_delegate(R, P...)(R function(P) fp) { return delegate R(P p) { return fp(p); }; } .. hope you like it..
Jul 18 2007
Daniel Korsgaard wrote:BCS wrote:R delegate(P) to_delegate(R, P...)(R function(P) fp) { auto dg = delegate R(P p) {return (cast(R function(P))(cast(void*)this))(p);} dg.ptr = cast(void*)fp; return dg; }
Err.. where do you get that 'this' from?
Aaahhh.... My Hat?? try this (totally bad form and all): R delegate(P) to_delegate(R, P...)(R function(P) fp) { struct S { R Go(P p) { return (cast(R function(P))(cast(void*)this))(p); } } return &(cast(S*)(cast(void*)fp)).Go; } void main() { auto dg = to_delegate(&hello); dg(5); } int hello(int i) { writef("hello world #%d\n", i); return 0; } (I actually tested this one)Anyways, my idea was to cut of the additional call. But if it really have to be there, this is a lot cleaner: R delegate(P) to_delegate(R, P...)(R function(P) fp) { return delegate R(P p) { return fp(p); }; } .. hope you like it..
And you walk right into the other gotcha of delegates[1], returning a delegate to a nested function or anon delegate is *really bad*. It carries a context pointer to stack space that, after the function returns, is unusable. Random results result. The same goes for keeping them around by any other means. [1] So many people miss it that there needs to be some size 24 blinking red bold notes next to a few sections of the spec about this.
Jul 18 2007
BCS wrote:Daniel Korsgaard wrote:BCS wrote:R delegate(P) to_delegate(R, P...)(R function(P) fp) { auto dg = delegate R(P p) {return (cast(R function(P))(cast(void*)this))(p);} dg.ptr = cast(void*)fp; return dg; }
Err.. where do you get that 'this' from?
Aaahhh.... My Hat?? try this (totally bad form and all): R delegate(P) to_delegate(R, P...)(R function(P) fp) { struct S { R Go(P p) { return (cast(R function(P))(cast(void*)this))(p); } } return &(cast(S*)(cast(void*)fp)).Go; } void main() { auto dg = to_delegate(&hello); dg(5); } int hello(int i) { writef("hello world #%d\n", i); return 0; } (I actually tested this one)
Looks promising :)Anyways, my idea was to cut of the additional call. But if it really have to be there, this is a lot cleaner: R delegate(P) to_delegate(R, P...)(R function(P) fp) { return delegate R(P p) { return fp(p); }; } .. hope you like it..
And you walk right into the other gotcha of delegates[1], returning a delegate to a nested function or anon delegate is *really bad*. It carries a context pointer to stack space that, after the function returns, is unusable. Random results result. The same goes for keeping them around by any other means. [1] So many people miss it that there needs to be some size 24 blinking red bold notes next to a few sections of the spec about this.
you are soo right.. believe it or not, but i was actually on my way to correct it, as it just popped op that the delegate context could/would dissaper right after the return.. :'(
Jul 18 2007









Robert Fraser <fraserofthenight gmail.com> 