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