www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Struct array assignment behaviour using example from Programming in D,

reply data pulverizer <data.pulverizer gmail.com> writes:
I have been playing with the matrix example given at the end of 
chapter 78 of Ali Çehreli's fabulous book and am having problems 
with overloading the opAssign operator.

rows is a private int[][] in a Matrix struct.

I have added the following ...

Matrix opAssign(int[][] arr)
{
     this.rows = arr;
     // rows = arr // does not work either ...
     return this;
}

However this does not work (no error occurs, it just doesn't do 
anything) but this does work ...

Matrix opAssign(int[][] arr)
{
     foreach(i, row; rows){
         row[] = arr[i];
     }
     return this;
}

The second is not efficient since it has to loop to assign the 
array. Is there a more efficient way of overwriting the array?
Mar 24 2016
next sibling parent data pulverizer <data.pulverizer gmail.com> writes:
On Thursday, 24 March 2016 at 17:24:38 UTC, data pulverizer wrote:
 I have been playing with the matrix example given at the end of 
 chapter 78 of Ali Çehreli's fabulous book and am having 
 problems with overloading the opAssign operator.

 rows is a private int[][] in a Matrix struct.

 I have added the following ...

 Matrix opAssign(int[][] arr)
 {
     this.rows = arr;
     // rows = arr // does not work either ...
     return this;
 }

 However this does not work (no error occurs, it just doesn't do 
 anything) but this does work ...

 Matrix opAssign(int[][] arr)
 {
     foreach(i, row; rows){
         row[] = arr[i];
     }
     return this;
 }

 The second is not efficient since it has to loop to assign the 
 array. Is there a more efficient way of overwriting the array?
Sorry. Please disregard. I'll drive home and ask this question properly!
Mar 24 2016
prev sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 03/24/2016 10:24 AM, data pulverizer wrote:
 I have been playing with the matrix example given at the end of chapter
 78 of Ali Çehreli's
For reference, it's "Multi-dimensional operator overloading example" here: http://ddili.org/ders/d.en/templates_more.html
having problems with overloading the opAssign operator.

 rows is a private int[][] in a Matrix struct.

 I have added the following ...

 Matrix opAssign(int[][] arr)
 {
      this.rows = arr;
      // rows = arr // does not work either ...
      return this;
 }

 However this does not work (no error occurs, it just doesn't do
 anything)
How are you testing it? The following worked for me: 1) Added that opAssign() to the struct. (Verified that it gets called.) 2) Tested with the following code: auto m2 = Matrix(); auto rows = [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ]; m2 = rows; writeln(m2); (I've tested with a dynamically generated 'rows' as well.) Ali
Mar 24 2016
parent reply data pulverizer <data.pulverizer gmail.com> writes:
On Thursday, 24 March 2016 at 18:46:14 UTC, Ali Çehreli wrote:
 On 03/24/2016 10:24 AM, data pulverizer wrote:
 I have been playing with the matrix example given at the end
of chapter
 78 of Ali Çehreli's
For reference, it's "Multi-dimensional operator overloading example" here: http://ddili.org/ders/d.en/templates_more.html
having problems with overloading the opAssign operator.

 rows is a private int[][] in a Matrix struct.

 I have added the following ...

 Matrix opAssign(int[][] arr)
 {
      this.rows = arr;
      // rows = arr // does not work either ...
      return this;
 }

 However this does not work (no error occurs, it just doesn't
do
 anything)
How are you testing it? The following worked for me: 1) Added that opAssign() to the struct. (Verified that it gets called.) 2) Tested with the following code: auto m2 = Matrix(); auto rows = [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ]; m2 = rows; writeln(m2); (I've tested with a dynamically generated 'rows' as well.) Ali
Thank you. Let me try to ask the question again. The problem I am experiencing is to do with opIndexAssign(). I added the following public operators: Matrix opAssign(int[][] arr) { writeln(__FUNCTION__); this.rows = arr; return this; } Matrix opAssign(Matrix mat) { writeln(__FUNCTION__); this.rows = mat.rows; return this; } Matrix opIndexAssign(A...)(int[][] arr, A arguments) if(A.length <= 2){ writeln(__FUNCTION__); Matrix subMatrix = opIndex(arguments); assert(((arr.length == subMatrix.nrow()) & (arr[0].length == subMatrix.ncol())), "Array dimension do not match matrix replacement.\n"); /*foreach(i, row; subMatrix.rows){ row[] = arr[i]; }*/ subMatrix = arr; // Does not work return subMatrix; } Matrix opIndexAssign(A...)(Matrix mat, A arguments) if(A.length <= 2){ writeln(__FUNCTION__); Matrix subMatrix = opIndex(arguments); assert(((mat.nrow() == subMatrix.nrow()) & (mat.ncol() == subMatrix.ncol())), "Array dimension do not match matrix replacement.\n"); /*foreach(i, row; subMatrix.rows){ row[] = mat.rows[i]; }*/ subMatrix = mat; // Does not work return subMatrix; } void main(){ // Here we test opAssign [][]int auto a = Matrix(); a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; // this works writeln(a); // opIndexAssign int[][] a[0..2, 0..2] = [[88, 88], [88, 88]]; // this does not work writeln(a); auto b = Matrix(); // opAssign Matrix b = a; // this works writeln(b); b = [[88, 88, 88, 88], [88, 88, 88, 88], [88, 88, 88, 88], [88, 88, 88, 88]]; // opIndexAssign Matrix b[0..3, 0..3] = a; // this does not work writeln(b); } If you uncomment the foreach lines, the opIndexAssign() work.
Mar 25 2016
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 03/25/2016 12:00 AM, data pulverizer wrote:
 On Thursday, 24 March 2016 at 18:46:14 UTC, Ali Çehreli wrote:
 On 03/24/2016 10:24 AM, data pulverizer wrote:
 I have been playing with the matrix example given at the end
of chapter
 78 of Ali Çehreli's
For reference, it's "Multi-dimensional operator overloading example" here: http://ddili.org/ders/d.en/templates_more.html
having problems with overloading the opAssign operator.
 Thank you. Let me try to ask the question again. The problem I am
 experiencing is to do with opIndexAssign().

 I added the following public operators:

      Matrix opAssign(int[][] arr)
      {
          writeln(__FUNCTION__);
          this.rows = arr;
          return this;
      }
The problem is due to the aliasing of 'rows' members of Matrix objects. subMatrix is supposed to be a reference into some elements of an existing Matrix. As soon as we do the above assignment, this Matrix (which may be a subMatrix in a specific context) breaks lose from its actual Matrix elements. We need to implement the function above "in place": Matrix opAssign(int[][] arr) { writeln(__FUNCTION__); if (rows.length < arr.length) { rows.length = arr.length; } foreach (i, row; arr) { const newLength = row.length; if (rows[i].length < newLength) { rows[i].length = newLength; } rows[i][0..newLength] = row[]; } return this; } (There must be an existing function that does that.)
      Matrix opAssign(Matrix mat)
      {
          writeln(__FUNCTION__);
          this.rows = mat.rows;
Same thing applies above: We need to assign to this.rows in place (which is easier by taking advantage of the previous function): this = mat.rows;
          return this;
      }
No changes needed for the other two functions but I would 'return this' instead of 'return subMatrix' for them as well. Ali
Mar 25 2016
parent data pulverizer <data.pulverizer gmail.com> writes:
On Friday, 25 March 2016 at 08:53:20 UTC, Ali Çehreli wrote:
 On 03/25/2016 12:00 AM, data pulverizer wrote:
 On Thursday, 24 March 2016 at 18:46:14 UTC, Ali Çehreli wrote:
 On 03/24/2016 10:24 AM, data pulverizer wrote:
 I have been playing with the matrix example given at the
end
 of chapter
 78 of Ali Çehreli's
For reference, it's "Multi-dimensional operator overloading
example"
 here:

   http://ddili.org/ders/d.en/templates_more.html

having problems with overloading the opAssign operator.
 Thank you. Let me try to ask the question again. The problem
I am
 experiencing is to do with opIndexAssign().

 I added the following public operators:

      Matrix opAssign(int[][] arr)
      {
          writeln(__FUNCTION__);
          this.rows = arr;
          return this;
      }
The problem is due to the aliasing of 'rows' members of Matrix objects. subMatrix is supposed to be a reference into some elements of an existing Matrix. As soon as we do the above assignment, this Matrix (which may be a subMatrix in a specific context) breaks lose from its actual Matrix elements. We need to implement the function above "in place": Matrix opAssign(int[][] arr) { writeln(__FUNCTION__); if (rows.length < arr.length) { rows.length = arr.length; } foreach (i, row; arr) { const newLength = row.length; if (rows[i].length < newLength) { rows[i].length = newLength; } rows[i][0..newLength] = row[]; } return this; } (There must be an existing function that does that.)
      Matrix opAssign(Matrix mat)
      {
          writeln(__FUNCTION__);
          this.rows = mat.rows;
Same thing applies above: We need to assign to this.rows in place (which is easier by taking advantage of the previous function): this = mat.rows;
          return this;
      }
No changes needed for the other two functions but I would 'return this' instead of 'return subMatrix' for them as well. Ali
That's great! Thank you very much for the fix and extra suggestions, and for your patience putting up with my poorly formulated question! Looks like I need to go and read all the structs and operators chapters thoroughly!
Mar 25 2016