digitalmars.D - easily convert any method/function to a delegate
- Daniel Korsgaard (44/44) Jul 18 2007 two simple function templates that together will enable you to
- Robert Fraser (2/56) Jul 18 2007
- BCS (13/35) Jul 18 2007 IIRC that doesn't (quite) work because some functions pass an arg in the...
- Daniel Korsgaard (11/54) Jul 18 2007 Aye ?!
- BCS (32/54) Jul 18 2007 Aaahhh.... My Hat??
- Daniel Korsgaard (5/68) Jul 18 2007 you are soo right.. believe it or not, but i was actually on my way to
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:Bummer :(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.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: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) { return 0; } (I actually tested this one)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..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:Looks promising :)BCS wrote: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) { return 0; } (I actually tested this one)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?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.. :'(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