opUnary with ++ and -- on a struct that has a dynamic array

2018-02-11 Thread aliak via Digitalmars-d-learn

Hi,

Is there a way to get post increment and pre increment working 
properly in this scenario?


import std.stdio;

struct A {
int[] a;
this(int a) { this.a = [a]; }
auto opUnary(string op)(){
return A(mixin(op ~ "this.a[0]"));
}
}

void main() {
auto a = A(0);
int b = 0;
writeln(a++, ":", b++); // 1, 0 <-- wrong post increment 
result

writeln(++a, ":", ++b); // 2, 2
}

If I switch the order of the mixin expression (i.e. "this.a[0]" ~ 
op) then the pre increment does not work.


Any tips?

Cheers
- Ali


Re: opUnary with ++ and -- on a struct that has a dynamic array

2018-02-11 Thread rumbu via Digitalmars-d-learn

On Monday, 12 February 2018 at 03:13:43 UTC, aliak wrote:

Hi,

Is there a way to get post increment and pre increment working 
properly in this scenario?


import std.stdio;

struct A {
int[] a;
this(int a) { this.a = [a]; }
auto opUnary(string op)(){
return A(mixin(op ~ "this.a[0]"));
}
}

void main() {
auto a = A(0);
int b = 0;
writeln(a++, ":", b++); // 1, 0 <-- wrong post increment 
result

writeln(++a, ":", ++b); // 2, 2
}


writeln(a++) translates to:

A copy = a;
a.opUnary!"++";
writeln(copy);

copy.a[] and a.a[] are the same reference, you increment 
a.a[0]/copy.a[0] in opUnary


to make this work you will need a postblit constructor:

struct A
{
   
   this(this)
   {
 a = a.dup; //make a copy a;
   }
}

In fact, you'll find exactly the same scenario in docs: 
https://dlang.org/spec/struct.html#struct-postblit




If I switch the order of the mixin expression (i.e. "this.a[0]" 
~ op) then the pre increment does not work.


Any tips?

Cheers
- Ali





Re: opUnary with ++ and -- on a struct that has a dynamic array

2018-02-12 Thread aliak via Digitalmars-d-learn

On Monday, 12 February 2018 at 06:16:21 UTC, rumbu wrote:

writeln(a++) translates to:

A copy = a;
a.opUnary!"++";
writeln(copy);

copy.a[] and a.a[] are the same reference, you increment 
a.a[0]/copy.a[0] in opUnary


to make this work you will need a postblit constructor:

struct A
{
   
   this(this)
   {
 a = a.dup; //make a copy a;
   }
}

In fact, you'll find exactly the same scenario in docs: 
https://dlang.org/spec/struct.html#struct-postblit




Ah! Awesome. Yes that works, thank you!

Cheers