Inner struct accessing host member

2014-08-05 Thread Philippe Sigaud via Digitalmars-d-learn

I'd have thought that this would work:

struct A
{
int[] i;
B b;

struct B
{
void foo() { i ~= 1;}
}
}

void main()
{
A a;
a.b.foo();
}

But the compiler tells me 'need this for i of type int[]'.
Is there any way I can gain access on i inside B?


Re: Inner struct accessing host member

2014-08-05 Thread Martijn Pot via Digitalmars-d-learn

On Tuesday, 5 August 2014 at 20:32:08 UTC, Philippe Sigaud wrote:

I'd have thought that this would work:

struct A
{
int[] i;
B b;

struct B
{
void foo() { i ~= 1;}
}
}

void main()
{
A a;
a.b.foo();
}

But the compiler tells me 'need this for i of type int[]'.
Is there any way I can gain access on i inside B?


I know I've read this in TDPL, but don't recall enough.

Does this help : 
http://www.digitalmars.com/d/archives/digitalmars/D/learn/Nested_struct_member_has_no_access_to_the_enclosing_class_data_38294.html 
?


Re: Inner struct accessing host member

2014-08-05 Thread Philippe Sigaud via Digitalmars-d-learn
On Tue, Aug 5, 2014 at 11:37 PM, Martijn Pot via Digitalmars-d-learn
 wrote:

> Does this help :
> http://www.digitalmars.com/d/archives/digitalmars/D/learn/Nested_struct_member_has_no_access_to_the_enclosing_class_data_38294.html

Yes, that helps: that explains why it does not wor :).
I changed my code to use classes. It's a bit less handy, but it works.


Re: Inner struct accessing host member

2014-08-05 Thread Philippe Sigaud via Digitalmars-d-learn
> why it does not wor :).

why it does not *work*, of course. Sigh.


Re: Inner struct accessing host member

2014-08-05 Thread abanstadya via Digitalmars-d-learn

On Tuesday, 5 August 2014 at 20:32:08 UTC, Philippe Sigaud wrote:

I'd have thought that this would work:

struct A
{
int[] i;
B b;

struct B
{
void foo() { i ~= 1;}
}
}

void main()
{
A a;
a.b.foo();
}

But the compiler tells me 'need this for i of type int[]'.
Is there any way I can gain access on i inside B?


programming Q, either youra newb or not, should rather be posted 
to 'http://forum.dlang.org/group/digitalmars.D.learn'. Your post 
appears on 'http://forum.dlang.org/group/digitalmars.D' which is 
more related to the lang. design rather to programming Q. Take 
care next time bro.




Re: Inner struct accessing host member

2014-08-05 Thread Era Scarecrow via Digitalmars-d-learn

On Tuesday, 5 August 2014 at 20:32:08 UTC, Philippe Sigaud wrote:

But the compiler tells me 'need this for i of type int[]'.
Is there any way I can gain access on i inside B?



 Been thinking about this a bit. I know some of my relies are in 
the 2012 fourm posts regarding it, but access permissions seems 
like the biggest reason, or rather lack of control of them.


 So take your example:


struct A
{
int[] i;
B b;
}


 Now let's make a couple instances of it; And assume it would 
work...


 A a;
 immutable A i_a;

 a.b.foo(); //fine
 i_a.b.foo(); //won't run, due to not being const/immutable

 So, a user decides let's copy the inner struct. If the struct 
copies it's attached secondary pointer going to it's outer/host, 
then:


 A.B b = a.b;
 A.B i_b = i_a.b;
 A.B broken_b = cast(A.B) i_a.b;

 b.foo(); //attached to a still, works...
 i_b.foo(); //const or immutable, won't work.
 broken_b.foo(); //i_a is accessible invisibly because overridden 
or transformed assuming it would be converted or copied/moved as 
appropriate.


 return b; //if a is a local variable then b becomes invalid even 
though it's a struct.

 return i_b; //same as return b
 return broken_b; //same as above two cases.




 inner structs in a function where the struct is never passed 
outside the function would probably work though...


void func() {
  int[] i;
  struct B {
void foo() { i ~= 1;}
  }

  B b;

  b.foo(); //passed a reference to the current frame along with 
it's local 'this', but since it never leaves the function it's 
safe.

}




 Now a current way to make it safe while still leaving it structs 
could be passing a reference to either the outer struct or the 
variable in question. For simplicity it would probably be the 
struct.


struct A
{
int[] i;
B b;

struct B
{
void foo(ref A outer) { outer.i ~= 1;}
}

void bar() //call B foo
{
b.foo(this);
}
}

 Or less safe is to use a pointer and assign it when b 
instantiates to point back to A.. But if you pass B around 
without A and A goes out of scope... same problem...


 Maybe i'm over-thinking it.


Re: Inner struct accessing host member

2014-08-05 Thread Artur Skawina via Digitalmars-d-learn
On 08/05/14 22:32, Philippe Sigaud via Digitalmars-d-learn wrote:
> I'd have thought that this would work:
> 
> struct A
> {
> int[] i;
> B b;
> 
> struct B
> {
> void foo() { i ~= 1;}
> }
> }
> 
> void main()
> {
> A a;
> a.b.foo();
> }
> 
> But the compiler tells me 'need this for i of type int[]'.
> Is there any way I can gain access on i inside B?

Not directly, but as you ask for /any/ way -- yes:

   struct B
   {
 void foo() { outer.i ~= 1; }
 ref A outer() inout @property { return 
*cast(A*)(cast(void*)&this-A.b.offsetof); }
   }

Note this will work only as long as you have just one B
instance in A and B is never created or copied outside of A.

artur


Re: Inner struct accessing host member

2014-08-05 Thread Philippe Sigaud via Digitalmars-d-learn

On Tuesday, 5 August 2014 at 22:14:23 UTC, abanstadya wrote:

programming Q, either youra newb or not, should rather be 
posted to 'http://forum.dlang.org/group/digitalmars.D.learn'. 
Your post appears on 
'http://forum.dlang.org/group/digitalmars.D' which is more 
related to the lang. design rather to programming Q. Take care 
next time bro.


This *is* D.learn, bro.


Re: Inner struct accessing host member

2014-08-05 Thread Philippe Sigaud via Digitalmars-d-learn
On Tuesday, 5 August 2014 at 23:47:00 UTC, Artur Skawina via 
Digitalmars-d-learn wrote:



Is there any way I can gain access on i inside B?


Not directly, but as you ask for /any/ way -- yes:

   struct B
   {
 void foo() { outer.i ~= 1; }
 ref A outer() inout @property { return 
*cast(A*)(cast(void*)&this-A.b.offsetof); }

   }

Note this will work only as long as you have just one B
instance in A and B is never created or copied outside of A.


OK. I have en entire graph, whose nodes are Bs inside A. So that 
might not be totally appropriate for me. Thanks anyway, I always 
forget about offsetof


Re: Inner struct accessing host member

2014-08-05 Thread Philippe Sigaud via Digitalmars-d-learn

Era:
 broken_b.foo(); //i_a is accessible invisibly because 
overridden or transformed assuming it would be converted or 
copied/moved as appropriate.


 return b; //if a is a local variable then b becomes invalid 
even though it's a struct.

 return i_b; //same as return b
 return broken_b; //same as above two cases.


I see. I didn't know one could create an A.B 'outside'. I saw 
inner types as Voldemort types, but that is true only for inner 
structs in functions.




 Now a current way to make it safe while still leaving it 
structs could be passing a reference to either the outer struct 
or the variable in question. For simplicity it would probably 
be the struct.

(...)
 Or less safe is to use a pointer and assign it when b 
instantiates to point back to A.. But if you pass B around 
without A and A goes out of scope... same problem...


 Maybe i'm over-thinking it.


I already tried to propagate a ref through A's methods, but that 
made a mess: I have lots of methods, which have all to transmit 
this ref, only for *one* of them being able to update it.


Thanks for you explanations :)
I'm now using classes and inner classes. I'm not fond of classes, 
but that's working correctly.


Re: Inner struct accessing host member

2014-08-05 Thread Era Scarecrow via Digitalmars-d-learn
On Wednesday, 6 August 2014 at 05:53:55 UTC, Philippe Sigaud 
wrote:
I see. I didn't know one could create an A.B 'outside'. I saw 
inner types as Voldemort types, but that is true only for inner 
structs in functions.


 But we weren't creating them, we were copying them, no 
constructors were used. If the struct is private that may follow 
different rules as the struct can't leave the outer struct. hmmm 
static and private... other keywords to try, but offhand it's 
been a while i don't know if either would change the behavior. 
Could just be inner scope limitations. Might be other 
tags/modifiers...


 I feel helpless :(


I already tried to propagate a ref through A's methods, but 
that made a mess: I have lots of methods, which have all to 
transmit this ref, only for *one* of them being able to update 
it.


Thanks for you explanations :)
I'm now using classes and inner classes. I'm not fond of 
classes, but that's working correctly.


 I'm not sure if it would help, but sometimes if you reverse the 
logic you might get what you want by putting the data in B 
instead of A.


 The example coming to mind is from the game 'Mark of the Ninja'. 
In order to speed up and get their code to work how they wanted, 
instead of having guards listen for sounds (which would be a 
constant pinging to look for sounds and other effects), the sound 
listened for the guards and notified them...


 So if the data is in B, A can access B's data; Although if you 
have another class C next to B, then communication between them 
becomes more of a pain probably...


 Just something to consider


Re: Inner struct accessing host member

2014-08-06 Thread Philippe Sigaud via Digitalmars-d-learn
> hmmm static and private... other keywords to
> try, but offhand it's been a while i don't know if either would change the
> behavior. Could just be inner scope limitations. Might be other
> tags/modifiers...
>
>  I feel helpless :(

No need to ;-) Thanks for your help, don't sweat it too much.

>  I'm not sure if it would help, but sometimes if you reverse the logic you
> might get what you want by putting the data in B instead of A.

I have a lot of Bs (nodes in a graph). They compute some things and
when they get a result, they update A's field. Each A holds the entry
point to their inner graph of Bs and waits for the results.
So I don't see how I could invert it, really.

What  *could* do it to have the graph of Bs in thread and sending
results as messages to another thread, where A is waiting for them.

It's just... I'm so used to being able to mix and compose 'concepts'
in D: structs in functions, classes in classes in structs, functions
returning functions returning structs, etc. I'm used to begin able to
organise my code as I see the problem space.
But here, with a struct-in-a-struct, I hit a wall. Not fun, but not
problematic too...