Discussion:
[fpc-devel] Array assignment operator
Schindler Karl-Michael
2018-11-03 11:56:29 UTC
Permalink
Hi

I would like to use a simple assignment operator for arrays, with which all elements of an array are assigned to the same value, similar to an extended initialize, not to zero but to a value of choice. A simple example for an integer array would be:

myArray := 5;

With arrays with defined bounds, it works, but i was not able to do it with a dynamic array. My test case is this:

program arrayAssign;

type
TmyArray = array of integer;

var
myArray: TmyArray;
index: integer;

operator := (const number: integer) theResult: TmyArray;
var
i: integer;
begin
for i := low(theResult) to high(theResult) do
theResult[i] := number;
end;

begin
setlength(myArray, 10);
writeln ('myArray: ', low(myArray), ', ', high(myArray));

myArray := 5;

writeln ('myArray: ', low(myArray), ', ', high(myArray));
for index := low(myArray) to high(myArray) do
writeln (index, ': ', myArray[index]);
end.

The output is:

myArray: 0, 9
myArray: 0, -1

The problem is that in the declaration of the operator, the functions low and high seem to return the values of the type TmyArray, i.e. 0 and -1 and not the values of the variable of the assignment statement, i.e. myArray and the assignment nullifies the previous setlength. Is there any way around this and obtain the actual values of myArray?

Michael, aka MiSchi.
_______________________________________________
fpc-devel maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-
Ben Grasset
2018-11-03 20:14:23 UTC
Permalink
On Sat, Nov 3, 2018 at 8:01 AM Schindler Karl-Michael <
Post by Schindler Karl-Michael
Hi
I would like to use a simple assignment operator for arrays, with which
all elements of an array are assigned to the same value, similar to an
extended initialize, not to zero but to a value of choice. A simple example
myArray := 5;
With arrays with defined bounds, it works, but i was not able to do it
program arrayAssign;
type
TmyArray = array of integer;
var
myArray: TmyArray;
index: integer;
operator := (const number: integer) theResult: TmyArray;
var
i: integer;
begin
for i := low(theResult) to high(theResult) do
theResult[i] := number;
end;
begin
setlength(myArray, 10);
writeln ('myArray: ', low(myArray), ', ', high(myArray));
myArray := 5;
writeln ('myArray: ', low(myArray), ', ', high(myArray));
for index := low(myArray) to high(myArray) do
writeln (index, ': ', myArray[index]);
end.
myArray: 0, 9
myArray: 0, -1
The problem is that in the declaration of the operator, the functions low
and high seem to return the values of the type TmyArray, i.e. 0 and -1 and
not the values of the variable of the assignment statement, i.e. myArray
and the assignment nullifies the previous setlength. Is there any way
around this and obtain the actual values of myArray?
Michael, aka MiSchi.
_______________________________________________
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
There's two issues:
1) The result of the operator is always a new, unique array (as in it's
unrelated to the myArray variable)
2) Your operator doesn't initialize the result with a length, so it's just
iterating over nothing.

Here's an example of the correct way to write the operator and use it:

program ArrayOverloads;

{$mode ObjFPC}

type TIntArray = array of Integer;

operator := (const I: Integer): TIntArray; inline;
var V: Integer;
begin
SetLength(Result, I);
for V := 0 to Pred(I) do Result[V] := V;
end;

var
I: Integer;
IA: TIntArray;

begin
IA := 25;
for I in IA do Write(I, ' ');
WriteLn;
for I := High(IA) downto 0 do Write(I, ' ');
WriteLn;
for I := Low(IA) to High(IA) do Write(I, ' ');
WriteLn;
I := 0;
while I < Pred(High(IA)) do begin
Inc(I, 2);
Write(I, ' ');
end;
end.

Output:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
2 4 6 8 10 12 14 16 18 20 22 24
Gennady Agranov
2018-11-03 20:43:36 UTC
Permalink
Hi,

Leaving aside the reason why the MiSchi's solution doesn't work the main
question is still not answered :)

If you have integer dynamic array "MyArray" is there a way for the
following statement to compile and work correctly:

MyArray := 5;

Thanks,
Gennady
Post by Ben Grasset
On Sat, Nov 3, 2018 at 8:01 AM Schindler Karl-Michael
Hi
I would like to use a simple assignment operator for arrays, with
which all elements of an array are assigned to the same value,
similar to an extended initialize, not to zero but to a value of
  myArray := 5;
With arrays with defined bounds, it works, but i was not able to
program arrayAssign;
type
  TmyArray = array of integer;
var
  myArray: TmyArray;
  index: integer;
operator := (const number: integer) theResult: TmyArray;
  var
    i: integer;
  begin
    for i := low(theResult) to high(theResult) do
      theResult[i] := number;
  end;
begin
  setlength(myArray, 10);
  writeln ('myArray: ', low(myArray), ', ', high(myArray));
  myArray := 5;
  writeln ('myArray: ', low(myArray), ', ', high(myArray));
  for index := low(myArray) to high(myArray) do
    writeln (index, ': ', myArray[index]);
end.
myArray: 0, 9
myArray: 0, -1
The problem is that in the declaration of the operator, the
functions low and high seem to return the values of the type
TmyArray, i.e. 0 and -1 and not the values of the variable of the
assignment statement, i.e. myArray and the assignment nullifies
the previous setlength. Is there any way around this and obtain
the actual values of myArray?
Michael, aka MiSchi.
_______________________________________________
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
1) The result of the operator is always a new, unique array (as in
it's unrelated to the myArray variable)
2) Your operator doesn't initialize the result with a length, so it's
just iterating over nothing.
program ArrayOverloads;
{$mode ObjFPC}
type TIntArray = array of Integer;
  operator := (const I: Integer): TIntArray; inline;
  var V: Integer;
  begin
    SetLength(Result, I);
    for V := 0 to Pred(I) do Result[V] := V;
  end;
var
  I: Integer;
  IA: TIntArray;
begin
  IA := 25;
  for I in IA do Write(I, ' ');
  WriteLn;
  for I := High(IA) downto 0 do Write(I, ' ');
  WriteLn;
  for I := Low(IA) to High(IA) do Write(I, ' ');
  WriteLn;
  I := 0;
  while I < Pred(High(IA)) do begin
    Inc(I, 2);
    Write(I, ' ');
  end;
end.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
2 4 6 8 10 12 14 16 18 20 22 24
_______________________________________________
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Ben Grasset
2018-11-03 21:00:01 UTC
Permalink
Post by Gennady Agranov
Hi,
Leaving aside the reason why the MiSchi's solution doesn't work the main
question is still not answered :)
If you have integer dynamic array "MyArray" is there a way for the
MyArray := 5;
Uh, yes? That's what my example showed.
Schindler Karl-Michael
2018-11-04 11:18:08 UTC
Permalink
Subject: Re: Array assignment operator
Content-Type: text/plain; charset="utf-8"
Post by Gennady Agranov
Hi,
Leaving aside the reason why the MiSchi's solution doesn't work the main
question is still not answered :)
If you have integer dynamic array "MyArray" is there a way for the
MyArray := 5;
Uh, yes? That's what my example showed.
In your example the length of the array was set to the number and the elements of the array assigned to their index, whereas my intention is to keep the length of the array and fill all elements to the same number.
_______________________________________________
fpc-devel maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-
Sven Barth via fpc-devel
2018-11-04 16:24:31 UTC
Permalink
Am So., 4. Nov. 2018, 12:23 hat Schindler Karl-Michael <
Post by Schindler Karl-Michael
Subject: Re: Array assignment operator
Message-ID: <
Content-Type: text/plain; charset="utf-8"
Post by Gennady Agranov
Hi,
Leaving aside the reason why the MiSchi's solution doesn't work the main
question is still not answered :)
If you have integer dynamic array "MyArray" is there a way for the
MyArray := 5;
Uh, yes? That's what my example showed.
In your example the length of the array was set to the number and the
elements of the array assigned to their index, whereas my intention is to
keep the length of the array and fill all elements to the same number.
The operator always creates a new array and does not modify the existing
one.
You'd need to abuse a binary operator (e.g. >< or even <=) for this.

Regards,
Sven
Gennady Agranov
2018-11-04 19:36:25 UTC
Permalink
Post by Sven Barth via fpc-devel
Am So., 4. Nov. 2018, 12:23 hat Schindler Karl-Michael
Subject: Re: Array assignment operator
Content-Type: text/plain; charset="utf-8"
On Sat, Nov 3, 2018 at 4:44 PM Gennady Agranov
Post by Gennady Agranov
Hi,
Leaving aside the reason why the MiSchi's solution doesn't work
the main
Post by Gennady Agranov
question is still not answered :)
If you have integer dynamic array "MyArray" is there a way for the
MyArray := 5;
Uh, yes? That's what my example showed.
In your example the length of the array was set to the number and
the elements of the array assigned to their index, whereas my
intention is to keep the length of the array and fill all elements
to the same number.
The operator always creates a new array and does not modify the
existing one.
You'd need to abuse a binary operator (e.g. >< or even <=) for this.
Regards,
Sven
_______________________________________________
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
I was thinking that type helper might work - e.g. MyArray.SetValue(5)
and with using properties MyArray.Value := 5

But seems that even simple type helper is not working anymore?

E.g. I was not able to compile example from
http://wiki.freepascal.org/Helper_types :(

TTypeHelper= type helperfor Integer
procedure SetZero;
end;

Thanks,

Gennady
Sven Barth via fpc-devel
2018-11-04 22:24:44 UTC
Permalink
Post by Sven Barth via fpc-devel
Am So., 4. Nov. 2018, 12:23 hat Schindler Karl-Michael <
Post by Schindler Karl-Michael
Subject: Re: Array assignment operator
Message-ID: <
Content-Type: text/plain; charset="utf-8"
On Sat, Nov 3, 2018 at 4:44 PM Gennady Agranov <
Post by Gennady Agranov
Hi,
Leaving aside the reason why the MiSchi's solution doesn't work the
main
Post by Gennady Agranov
question is still not answered :)
If you have integer dynamic array "MyArray" is there a way for the
MyArray := 5;
Uh, yes? That's what my example showed.
In your example the length of the array was set to the number and the
elements of the array assigned to their index, whereas my intention is to
keep the length of the array and fill all elements to the same number.
The operator always creates a new array and does not modify the existing
one.
You'd need to abuse a binary operator (e.g. >< or even <=) for this.
Regards,
Sven
_______________________________________________
I was thinking that type helper might work - e.g. MyArray.SetValue(5) and
with using properties MyArray.Value := 5
But seems that even simple type helper is not working anymore?
E.g. I was not able to compile example from
http://wiki.freepascal.org/Helper_types :(
TTypeHelper = type helper for Integer
procedure SetZero;end;
Did you add {$modeswitch typehelpers}?
If so, what is the error you get?

Regards,
Sven
Gennady Agranov
2018-11-05 00:00:03 UTC
Permalink
Am So., 4. Nov. 2018, 20:36 hat Gennady Agranov
Post by Sven Barth via fpc-devel
Am So., 4. Nov. 2018, 12:23 hat Schindler Karl-Michael
Am 04.11.2018 um 12:00 schrieb Ben Grasset
To: FPC-Devel users discussions
Subject: Re: Array assignment operator
Content-Type: text/plain; charset="utf-8"
On Sat, Nov 3, 2018 at 4:44 PM Gennady Agranov
Post by Gennady Agranov
Hi,
Leaving aside the reason why the MiSchi's solution doesn't
work the main
Post by Gennady Agranov
question is still not answered :)
If you have integer dynamic array "MyArray" is there a way
for the
Post by Gennady Agranov
MyArray := 5;
Uh, yes? That's what my example showed.
In your example the length of the array was set to the number
and the elements of the array assigned to their index,
whereas my intention is to keep the length of the array and
fill all elements to the same number.
The operator always creates a new array and does not modify the
existing one.
You'd need to abuse a binary operator (e.g. >< or even <=) for this.
Regards,
Sven
_______________________________________________
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
I was thinking that type helper might work - e.g.
MyArray.SetValue(5) and with using properties MyArray.Value := 5
But seems that even simple type helper is not working anymore?
E.g. I was not able to compile example from
http://wiki.freepascal.org/Helper_types :(
TTypeHelper= type helperfor Integer
procedure SetZero;
end;
Did you add {$modeswitch typehelpers}?
If so, what is the error you get?
Regards,
Sven
_______________________________________________
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
My error was caused by the fact that I was using delphi mode - when I
used the mode switch it worked perfectly :)

The original problem is solved - at least the way I see it - in FPC you
can add method to the array :)

Cool!

Thanks!

{$MODESWITCH TYPEHELPERS}

program arrayset;

type
  abc = array of integer;
  abc_helper = type helper for abc
  procedure SetValue(value: integer);
  procedure Print;
end;

procedure abc_helper.SetValue(value: integer);
var
  i: integer;
begin
  for i := Low(self) to High(self) do
    self[i] := value;
end;

procedure abc_helper.Print;
var
  i: integer;
begin
  for i := Low(self) to High(self) do
    Writeln('[',i,'] = ',self[i]);
end;

var
  a: abc;
begin
  SetLength(a,10);
  a.SetValue(5);
  a.Print;
end.
Sven Barth via fpc-devel
2018-11-05 10:06:38 UTC
Permalink
Post by Sven Barth via fpc-devel
Post by Sven Barth via fpc-devel
Am So., 4. Nov. 2018, 12:23 hat Schindler Karl-Michael <
Post by Schindler Karl-Michael
Subject: Re: Array assignment operator
Message-ID: <
Content-Type: text/plain; charset="utf-8"
On Sat, Nov 3, 2018 at 4:44 PM Gennady Agranov <
Post by Gennady Agranov
Hi,
Leaving aside the reason why the MiSchi's solution doesn't work the
main
Post by Gennady Agranov
question is still not answered :)
If you have integer dynamic array "MyArray" is there a way for the
MyArray := 5;
Uh, yes? That's what my example showed.
In your example the length of the array was set to the number and the
elements of the array assigned to their index, whereas my intention is to
keep the length of the array and fill all elements to the same number.
The operator always creates a new array and does not modify the existing
one.
You'd need to abuse a binary operator (e.g. >< or even <=) for this.
Regards,
Sven
_______________________________________________
I was thinking that type helper might work - e.g. MyArray.SetValue(5) and
with using properties MyArray.Value := 5
But seems that even simple type helper is not working anymore?
E.g. I was not able to compile example from
http://wiki.freepascal.org/Helper_types :(
TTypeHelper = type helper for Integer
procedure SetZero;end;
Did you add {$modeswitch typehelpers}?
If so, what is the error you get?
Regards,
Sven
_______________________________________________
My error was caused by the fact that I was using delphi mode - when I used
the mode switch it worked perfectly :)
In mode Delphi you need to use "record helper" for primitive types as
Delphi does not use "type helper" for that.

Regards,
Sven
Loading...