April 16, 2007
I have a function template that specializes on a int. Pointers to these functions are placed into a table and called at various points. The only difference between the different versions of the template is that each one puts the given int into a struct and returns it. The problem is that there ends up being about 200K of code bloat from this.

What I'm looking to do is switch to delegates where the this pointer is used to carry the value. To do this I plan to make a struct with a single method that does what I need. Then I'll cast the value that is to be put into the struct to a pointer and build a delegate from it.

This will actual work because the this pointer will never get used as a pointer. Here is an example that uses the same trick to convert a function to a delegate.

|R delegate(Args) ToDelegate(R, Args...)(R function(Args) func)
|{
| struct S
| {
|  void callMe(Args args)
|  {
|   return (cast(R function(Args))cast(void*)this)(args);
|  }
| }
| return &((cast(S*)cast(void*)func).callMe);
|}


The problem shows up when I try to make the int -> struct* conversion work a compile time. This is what I'm trying (cut down a bit):

|struct Stub
|{
| int Foo()
| {
|  return cast(int)this;
| }
|}
|
|template Bar(int i)
|{
| const int delegate() Bar = &(cast(Stub*)i).Foo;
|}

Because I want to put it into a static const array, The value can't be built at compile time.

what I'm doing for now is this

|union Build
|{
| int delegate() dg;
| uint[2] data;
|}
|
|template Go(int i)
|{
| private const Build d = {data:[cast(uint)i, cast(uint)&Stub.Foo]};
| const int delegate() Go = d.dg;
|}

Not vary safe but it work, sometimes. Other times DMD seems to think that you can't get the address of Stub.Foo. That one showed up when I tried to, at compile time, build a delegate with null for the this pointer (it used no local members so that shouldn't be a problem)

Any ideas on how to do this? Language extensions would work but I'd really like to keep it all D V1.0.


April 17, 2007
Reply to Benjamin a.k.a. BCS,

I have managed to side step the issue by building the delegates at runtime. Not as neat, but it at least compiles.