static code generation

js.mdnq js_adddot+mdng at gmail.com
Thu Dec 20 17:48:06 PST 2012


On Thursday, 20 December 2012 at 04:17:48 UTC, r_m_r wrote:
> On 12/18/2012 04:42 AM, js.mdnq wrote:
>> It looks like the approach 2 does what I'm looking for pretty 
>> nicely
>> except that, If I'm not mistaken the user struct will error 
>> out when
>> trying to access members from the master.
>
> Another approach that works: http://dpaste.dzfl.pl/966d9f3a
> (could have been very simple if ``multiple alias this'' was 
> available).
>
> regards,
> r_m_r

I see what you are doing and it is a possible good approach. 
There are 2 issues I have with it:

1. Wrapping the members could be a performance hit if D does not 
inline. This isn't so much of an issue with the method but of D 
as it seems not to inline well. It's really not a big deal though 
at this point.

2. More serious is the inability to access elements from one 
struct in another.  E.g., You should have some way to access 
S_A's members from S_B. This is difficult to do properly though 
since S_B generally shouldn't know about S_A.

You can insert a reference to A inside B to do this, and this 
leads to the same issues I came across with nested structs. You 
end up not needing that ptr in the composite class(your S_ABC) 
since everything is offset from each other. So you could go down 
the route I went(or try and some up with another solution) to 
make this work.


For example, possibly a simpler way to do this is:

struct S_AB(bool _NestLevel)
{
     ...
     public:
        struct S_A(int _Offset) { S_B B_f() { 'return B;' } }
        struct S_B(int _Offset) { S_A A_f() { 'return A;' } }

     mixin S_A sA; mixin S_B sB;

     GenUnion(...)
}

Where GenUnion is your mixin technique that wraps all members of 
S_A and S_B. Basically combining our techniques. That way no 
extra pointers are wasted AND we have access to "siblings".

One problem with your method is it is more of a product rather 
than a union. A true union will allow duplicates and not store 
them. Technically we do not wrap the members but store everything 
in the composite class. Any "overlap" between the sub structures 
will produce only one "copy".

e.g.,

struct S_A { int x; }
struct S_B { int x; }

then GenUnion(S_A, S_B) will produce a struct like S_AB { int x; }

in your method, you have two x's.

Now it might be impossible to efficiently generate at true union 
in D at the moment and your method may be the only 
possibility(which, is more of a product).   If we could get a the 
struct's code rather than just the member declarations then it 
would be rather easy.

struct S_A { int x; int y; void func(); void funcA(); }
struct S_B { int x; int z; void func(); void funcB(); }

then GenUnion(S_A, S_B) will produce a struct like
S_AB
{
    int x;
    int y;
    void func();
    void funcA();
    void funcB();
}

Note that S_AB does not waste space. size(S_AB) < size(S_A) + 
size(S_B). Issues may arise if, say, S_A.func != S_B.func. Ways 
around this is to generate an error, warn, OR, we could use your 
method and has "perspectives"

e.g.,


S_AB()
{
    string Perspective = "A";
    S_A sA; S_B sB;
    ...
    void func() { if (Perspective == "A") sA.func(); else 
sB.func(); }
    ...
}


In which case we have sort of run-time polymorphism(or you could 
make it compile time by using a static if instead). S_AB can 
change it's behavior just by setting the "perspective". This 
could be lead to problems conceptually since we generally do not 
think of structs behaving like this.

It would, though, make more GenStruct more union like since the 
wrappers are not qualified(which produces a more product like 
structure).

I think, but not totally sure, that the above method of 
perspectives is essentially a sort of of set "inheritance"(not 
parent child but through siblings though),

For example, if A is human and B is mammal the S_AB can be made 
to be a human or a mammal by setting it's "perspective" but it's 
it's really a union one can have unrelated things, so it is not 
quite the same thing as inheritance. It may be useful to create 
variant types since or possibly other things.

In any case, I think your on the right track to be able to get 
something useful out of it. I think, though, your limited to what 
you can achieve because of D's limitations of getting the code of 
things.

For me, the two things I would need from your method to use is: 
1. True union like behavior(it's ok to wrap but do not over 
qualify the member names). 2. The ability to access siblings 
without storing additional ptr's(I'm not sure if this is possible 
without access to the method code, my method of offsets might not 
work with a true union because it could change the struct's 
memory layout).

Thanks for your work.





More information about the Digitalmars-d-learn mailing list