Functors

BCS ao at pathlink.com
Thu Jun 28 14:29:17 PDT 2007


Reply to Craig,

> Very useful hack.  Thanks!
> 
> "BCS" <ao at pathlink.com> wrote in message
> news:ce0a3343b7368c987a5d27c1f2e at news.digitalmars.com...
> 
>> Reply to Craig,
>> 
>>>> if all you want to do is convert fn ptrs to delegates this works:
>>>> 
>>>> |T delegate(A) Fn2Dg(T, A...)(T function(A) f)
>>>> |{
>>>> | struct tmp
>>>> | {
>>>> | T ret(A args){ return (cast(T function(A))this)(args); }
>>>> | };
>>>> | return &(cast(tmp*)f).ret;
>>>> |}
>>> I didn't know this was possible.  Are you sure this works? I thought
>>> there were some issues with calling conventions.
>>> 
>>> -Craig
>>> 
>> What goes on there is that the context pointer (which is supposed to
>> be a object, struct or stack frame) is in fact a function pointer.
>> The calling convention for delegates never actually de references the
>> context pointer so what is is doesn't matter. In this case I convert
>> it back to a function pointer, and then call it with the arguments I
>> was given. All of the values in the arguments get copied and arranged
>> correctly for the function call and everything is fine and dandy.
>> 

It gets better <g type=evil> that 32 bits of the pointer can be used for 
anything as long as it isn't set to null

struct S
{
  union U
  {
    S* ptr;
    struct
    {
      short s;
      byte b;
      char c;
    }
  }

  void delegate() build(short s, byte b, char c)
  {
    U u;
    u.s=s; u.b=b; u.c=c;
    return &s.ptr.go;
  }

  void go()
  {
    U u;
    U.ptr = this;
    writef("%s, %s, %s\n", u.s, u.b, u.c);
  }
}





More information about the Digitalmars-d mailing list