View mode: basic / threaded / horizontal-split · Log in · Help
December 13, 2012
Re: Nested Structs (Solution)
On Wednesday, 12 December 2012 at 22:58:47 UTC, Max Samukha wrote:
> On Wednesday, 12 December 2012 at 22:19:54 UTC, js.mdnq wrote:
>> Also, I initially tried to do
>>
>> 	B!(A.b1.offsetof) b1;
>>
>> a'la
>>
>> http://forum.dlang.org/thread/mailman.2627.1355335532.5162.digitalmars-d@puremagic.com
>>
>> but dmd 2.060 crashes, which is why I moved on to using a 
>> static if.
>
> That's 'outer', yet another half-done D feature. It should be 
> implemented for nested structs.

It's not half-done. Structs are supposed to be POD. They should
contain exactly the members that you list; no more hidden stuff.
See TDPL 7.1.8 (p.262): "Unlike classes netsted within classes,
nested structs and nested classes within structs dont contain any
hidden member outer - there's no special code generated."
I am not sure about classes within structs but nested structs
should behave like they do IMHO.

Mafi
December 14, 2012
Re: Nested Structs (Solution)
On Thursday, 13 December 2012 at 20:56:05 UTC, Mafi wrote:
> On Wednesday, 12 December 2012 at 22:58:47 UTC, Max Samukha 
> wrote:
>> On Wednesday, 12 December 2012 at 22:19:54 UTC, js.mdnq wrote:
>>> Also, I initially tried to do
>>>
>>> 	B!(A.b1.offsetof) b1;
>>>
>>> a'la
>>>
>>> http://forum.dlang.org/thread/mailman.2627.1355335532.5162.digitalmars-d@puremagic.com
>>>
>>> but dmd 2.060 crashes, which is why I moved on to using a 
>>> static if.
>>
>> That's 'outer', yet another half-done D feature. It should be 
>> implemented for nested structs.
>
> It's not half-done. Structs are supposed to be POD. They should
> contain exactly the members that you list; no more hidden stuff.
> See TDPL 7.1.8 (p.262): "Unlike classes netsted within classes,
> nested structs and nested classes within structs dont contain 
> any
> hidden member outer - there's no special code generated."
> I am not sure about classes within structs but nested structs
> should behave like they do IMHO.
>
> Mafi

True nested structs do not contain hidden data. The data is 
attached. There is no reason why a nested struct should not have 
access to it's outer class EXCEPT to prevent copy issues. If one 
is simply using structs to wrap types inside a class for 
encapsulation then it should be able to access the class 
members... else it becomes somewhat of an orphan without much use.

Basically it's more of a matter of logical grouping. A class'es 
fields are laid out in memory sequentially. A struct field is 
just part of that layout.

01 Field
02 Field
03 Struct Field
   03.1 Field
   03.2 Field
04 Field
etc...

which can also be seen as

01 Field
02 Field
03 Field
04 Field
05 Field

the struct field's this ptr is always some fixed offset into the 
class, so it is easy to get the outer by a simple calculation(as 
I have demonstrated with the code I posted).

The usefulness, again, is that one can encapsulate(go from a 
class of nothing but fields to a class of structs) many pieces of 
functionality. But if the encapsulation prevents one from 
interaction with outer class members, then it can be too 
limiting. Nested classes solve this problem by storing a ptr to 
the class, that is ok, right? (it is necessary, my method won't 
work with classes since they are reference types)

But if it's ok with classes then why are nested structs required 
to be orphans OR store a ptr to the class, which bloats the 
struct?

The only thing "my" method does is stop one from having to store 
such a pointer to the class, which, for many cases, is redundant.

So, if you want to argue against my method, really you should 
then be arguing against the case

class A
{
   struct B{
     A a;
   }
}

because it is pretty much exactly the same except for one point: 
If we do away with the explicit ptr storage in the struct to save 
memory, we can't arbitrarily copy the nested structs to similar 
struct types. Alias this and opAssign help solve these problems 
though.

I think my code solves a very real problem of providing efficient 
encapsulation of class data and functionality. One doesn't have 
to have one large huge class full of tons of fields and methods 
but can break a class down into chunks and build a hierarchy, 
similar to inheritance, but without the overhead. (a sort of 
slimed down inheritance.

For my case, why I went down this pass, was to solve this problem:

class A {
   byte X;
   .. other stuff...
}

Suppose I need to "intercept" assignments to X to, say, mask the 
value or whatever. How? I could create a new type. I could use an 
external struct.

struct bbyte { byte x; alias x this; }

class A {
   bbyte X;
   .. other stuff...
}

but suppose X is always associated with A, it's never found alone 
so to speak. Suppose, I need to access something from A while in 
X:



class A {
   bbyte X;
   string Name;
   .. other stuff...
}


BUT, now bbyte is 4 times larger than it needs to be just to 
access A. Since I said X will always be part of A, we can do this:


class A {
   struct bbyte
   {
      byte x; alias x this;
      A a;
      void Do() { writeln(a.Name); }
   }
   bbyte X;
   string Name;
   .. other stuff...
}

which is simply more logical but nothing different.

BUT!!!! NOW! we can reduce the size of bbyte significantly:

class A {
   struct bbyte
   {
      byte x; alias x this;
      void Do() { writeln(outer.Name); }
   }
   bbyte X;
   string Name;
   .. other stuff...
}


To me, this is a huge improvement. Of course, to do this in D one 
has to "hack" it up.

As long as we don't create orphaned bbytes they always will have 
a parent. Since we are using them as "wrappers" we don't care all 
that much since any time they are used as "orphans" they are 
really just the value type they wrap. (through alias this and 
opAssign/cast)

In some sense, these types are not value types but simply part of 
the class but have compiler like encapsulation.

In any case, Just because everyone won't find it useful does not 
mean that it is not useful. Even if just a few people need some 
construct like this then it would be worthwhile to have. It 
really sucks when you need something and you don't have it.
December 14, 2012
Re: Nested Structs (Solution)
I guess the complicating factor is that a nested struct could not 
be copied out of one class into another of a different type, so I 
can see why it's not implemented. The compiler would have to 
prevent copies out, or the language would have to be modified to 
allow nesting but with some new convention to make it clear that 
the struct is nested, not sure if it's worth it though, you can 
always make do without it.

--rt
December 14, 2012
Re: Nested Structs (Solution)
On Friday, 14 December 2012 at 06:27:39 UTC, Rob T wrote:
> I guess the complicating factor is that a nested struct could 
> not be copied out of one class into another of a different 
> type, so I can see why it's not implemented. The compiler would 
> have to prevent copies out, or the language would have to be 
> modified to allow nesting but with some new convention to make 
> it clear that the struct is nested, not sure if it's worth it 
> though, you can always make do without it.
>
> --rt

This is why I suggested a new type earlier so that it is obvious 
something is different. Since my initial reason for needed such a 
structure was to wrap built in types to provide functionality 
it's not a big deal because one can override opAssign and use 
alias this. Doing so basically lets the "outside world" use the 
type as if it were the value type and when copied they are 
copying the built in types rather than the structs.


If it's a big deal it is not hard to create a duplicate struct 
with the added outer pointer similar to what is done with nested 
classes and then just copy over the data from one to the other. 
This will work fine except the need to create two structs with 
different, although, now that I think about it, I could 
potentially use a static if to create such a dual struct which 
would then help avoid orphans.

When an assignment from the struct is used it will return, not 
itself, but either it's value(if a wrapper) or this new struct 
which is identical except containing a ptr to it's parent. I'll 
try to add it and see how it works.
December 14, 2012
Re: Nested Structs (Solution)
http://dpaste.dzfl.pl/64025e0a

contains updated code. When the offset of the struct is 0 it 
contains an actual ptr to the class(the standard way) and hence 
can be "orphaned". When the offset is not 0 then it is part of a 
class object and can use a calculation to get the parent.

Both methods work somewhat easily together as demonstrated by the 
last example.

Unfortunately it seems we have to make an assignment.

A.B!(0) b = a.b1;

does not work but

A.B!(0) b;
b = a.b1;

does. Not sure if there is some way to make the first work.
December 14, 2012
Re: Nested Structs (Solution)
On Friday, 14 December 2012 at 07:39:33 UTC, js.mdnq wrote:
>
> Unfortunately it seems we have to make an assignment.
>
> A.B!(0) b = a.b1;

This one tries to call a constructor that takes in a 
typeof(a.b1). Do you have a constructor for it?

> does not work but
>
> A.B!(0) b;
> b = a.b1;
> does. Not sure if there is some way to make the first work.

--rt
December 14, 2012
Re: Nested Structs (Solution)
On Friday, 14 December 2012 at 09:47:18 UTC, Rob T wrote:
> On Friday, 14 December 2012 at 07:39:33 UTC, js.mdnq wrote:
>>
>> Unfortunately it seems we have to make an assignment.
>>
>> A.B!(0) b = a.b1;
>
> This one tries to call a constructor that takes in a 
> typeof(a.b1). Do you have a constructor for it?
>
>> does not work but
>>
>> A.B!(0) b;
>> b = a.b1;
>> does. Not sure if there is some way to make the first work.
>
> --rt

oh, thats what it does?!?!?! ;)  Ok, well, then it should be easy 
to add.
December 16, 2012
Re: Nested Structs (Solution)
There's an interesting discussion going on that may be related to 
this subject.

http://forum.dlang.org/thread/mailman.2705.1355596709.5162.digitalmars-d@puremagic.com

Note the definition with the "hidden reference frame" baggage, 
and to get rid of the extra baggage use "static struct".

The reference frame mentioned however is not for a parent class 
or struct, but maybe its similar enough that nested structs could 
possibly be extended with a hidden reference to the parent class 
or struct.

It all seems debatable though with various levels of 
complications associated with implementing a nest struct.

--rt
December 16, 2012
Re: Nested Structs (Solution)
On Sunday, 16 December 2012 at 01:04:44 UTC, Rob T wrote:
> There's an interesting discussion going on that may be related 
> to this subject.
>
> http://forum.dlang.org/thread/mailman.2705.1355596709.5162.digitalmars-d@puremagic.com
>
> Note the definition with the "hidden reference frame" baggage, 
> and to get rid of the extra baggage use "static struct".
>
> The reference frame mentioned however is not for a parent class 
> or struct, but maybe its similar enough that nested structs 
> could possibly be extended with a hidden reference to the 
> parent class or struct.
>
> It all seems debatable though with various levels of 
> complications associated with implementing a nest struct.
>
> --rt

I was just looking at that and thought it was pretty interesting 
and that maybe the technique I used might apply. But after second 
thought I don't think it will work because copies of the struct 
are passed around instead. Which, if you recall, is still 
somewhat of an issue with the nested struct model I'm using. Of 
course, with overrides of opAssign, this, and opCast one could 
possibly avoid this issue too.

It seems to me that the stack frame has taken place of the class 
object. When the voldemort struct is returned from the function, 
the outer values come from the stack frame(rather than the class 
object). When you return the voldemort struct, it also orphans it 
in a similar way it does for the class object. That is, unless 
the stack frame is always correct, which I haven't convinced 
myself of yet.

Although I have a solution using the nested struct idea 
directly(simply use a functor),  I think will work... I'll post 
it on the other thread. (this might imply that the voldemort 
construct is pretty solid, or can be made to be so)
Next ›   Last »
1 2
Top | Discussion index | About this forum | D home