www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - "overlapping" structs

This gets back to my question about nested structs(since I'm 
trying to find a way to make it work). Take the following working 
example:

class A {

     struct B {
         A* a;
     }

     B b1;
     B b2;
}

Wastes a lot of space as we store a ptr to A for each field we 
use. If there were 100 B types in A then it would bloat the class 
by 100*size_t. In theory it is possible to avoid this.

If we could pass an offset to a struct relative to another AND 
create a "virtual" variable at another offset then we could 
remove the overhead issue in the above case:


class A {
     A* a;
     struct B(Ofs) {
         virtual!(-Ofs) A* a;    // Our goal is to have this a be 
the a in A::a
     }

     B!(ofs a:$) b1;
     B!(ofs a:$) b2;
}

This might not make sense BUT it's pretty simple. ($ = here)

When b1 is created, we "pass" the distance from it to A::a. (in 
this case size_t). virtual!(-Ofs) "creates" a at this location... 
which just overlaps with A::a, which is the whole point. B::a 
does not take up any space inside the struct and essentially uses 
A::a.

When b2 is created, we pass it a slightly different 
offset(B.sizeof + size_t) but, it too will make b2.a overlap with 
A::a.

(there are two structs here, one for b1 and one for b2. They 
differ in their offset value)

The big difference between the two cases is, again, that the 2nd 
requires only one additional storage ptr while the first requires 
n ptr's.

Also, we could simplify it further since we don't technically 
need to use ptr's but that would require much more from the 
compiler. Hopefully there is some way to implement what I'm 
talking about in D using this method than the other(which is 
talked about more in the other post).

To prevent weird stuff from happening we prevent the structs from 
being directly copied so that their a's won't be garbage(since 
it's actually before the struct). So no default constructor for 
these types can be used ;/

(the easy way to fix it is to have methods inside the struct get 
passed the this and the cthis ptr(cthis is the pointer to the 
object containing in the struct))
Dec 10 2012