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.