Am 07.06.2019 um 18:37 schrieb Ben Grasset:
For example, consider the following code, that implements a generic
"memcpy"-style procedure using a static advanced-record method:
program Example;
{$mode Delphi}
type
TMem<T> = record
public type
PT = ^T;
public
class procedure Copy(Dest: PT; Src: PT; Len: PtrUInt); static; inline;
end;
class procedure TMem<T>.Copy(Dest: PT; Src: PT; Len: PtrUInt);
begin
while Len > 0 do begin
Dest^ := Src^;
Inc(Dest);
Inc(Src);
Dec(Len);
end;
end;
type
String4 = String[4];
var
X: TArray<String4> = ['AAAA', 'BBBB', 'CCCC', 'DDDD', 'EEEE'];
Y: TArray<String4> = ['', '', '', '', ''];
S: String4;
begin
TMem<String4>.Copy(@Y[0], @X[0], 5);
for S in Y do WriteLn(S);
end.
The only reason the record is necessary at all is to be able to
declare "PT" as a pointer type alias to the record's overall "T".
Personally, I'd much rather simply write the following, if it was
possible:
procedure MemCopy<T>(Dest: ^T; Src: ^T; Len: PtrUInt);
begin
while Len > 0 do begin
Dest^ := Src^;
Inc(Dest);
Inc(Src);
Dec(Len);
end;
end;
You can do it like this (yes, works in mode Delphi as well):
=== code begin ===
{$mode objfpc}
{$modeswitch advancedrecords}
type
generic TPointerType<T> = record
public type
PT = ^T;
end;
generic procedure MemCopy<T>(Dest, Src: specialize
TPointerType<T>.PT; Len: PtrUInt);
begin
while Len > 0 do begin
Dest^ := Src^;
Inc(Dest);
Inc(Src);
Dec(Len);
end;
end;
type
String4 = String[4];
var
X: specialize TArray<String4> = ('AAAA', 'BBBB', 'CCCC', 'DDDD', 'EEEE');
Y: specialize TArray<String4> = ('', '', '', '', '');
S: String4;
begin
specialize MemCopy<String4>(@Y[0], @X[0], 5);
for S in Y do WriteLn(S);
end.
=== code end ===
Regards,
Sven
_______________________________________________
fpc-devel maillist - fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel