[fpc-devel] [] property overloads
Ben Grasset
operator97 at gmail.com
Tue Jul 9 00:11:46 CEST 2019
On Mon, Jul 8, 2019 at 3:47 PM Ben Grasset <operator97 at gmail.com> wrote:
> On Mon, Jul 8, 2019 at 2:22 PM Ryan Joseph <genericptr at gmail.com> wrote:
>
>> and it will actually write to the actual record in the array and not a
>> returned copy. However due to how the properties are currently structured
>> this means we can’t use the setter without passing pointers
>>
>
> Ah, I see what you mean. Note you can at least work around this for now
> with operator overloading:
>
Also, here's a longer (but much better because it doesn't require the data
type provided by the user to itself be directly assignable to a pointer)
version of that:
program Example;
{$mode Delphi}{$H+}
uses SysUtils;
type
PVec3F = ^TVec3F;
TVec3F = record
X, Y, Z: Single;
end;
type
TList<T> = record
public type
PT = ^T;
TConverter = record
V: PT;
class operator Implicit(constref From: T): TConverter; inline;
class operator Implicit(const From: PT): TConverter; inline;
class operator Implicit(constref From: TConverter): PT; inline;
end;
strict private
FData: array of TConverter;
private
function GetItem(const I: PtrUInt): TConverter; inline;
procedure SetItem(const I: PtrUInt; const Val: TConverter); inline;
function GetLength: PtrInt; inline;
procedure SetLength(const I: PtrInt); inline;
public
property Items[const I: PtrUInt]: TConverter read GetItem write
SetItem; default;
property Length: PtrInt read GetLength write SetLength;
end;
class operator TList<T>.TConverter.Implicit(constref From: T): TConverter;
begin
Result.V := @From;
end;
class operator TList<T>.TConverter.Implicit(const From: PT): TConverter;
begin
Result.V := From;
end;
class operator TList<T>.TConverter.Implicit(constref From: TConverter):
PT;
begin
Result := From.V;
end;
function TList<T>.GetItem(const I: PtrUInt): TConverter;
begin
if I < System.Length(FData) then
Result := FData[I]
else
Result := nil;
end;
procedure TList<T>.SetItem(const I: PtrUInt; const Val: TConverter);
begin
if I < System.Length(FData) then
FData[I] := Val;
end;
function TList<T>.GetLength: PtrInt;
begin
Result := System.Length(FData);
end;
procedure TList<T>.SetLength(const I: PtrInt);
begin
System.SetLength(FData, I);
end;
const
DEFAULT_VEC3F: TVec3F = (
X: 0.0;
Y: 0.0;
Z: 0.0;
);
var
PVec: PVec3F;
VecList: TList<TVec3F>;
begin
VecList.Length := 2;
// So, you can directly assign to the list by value...
VecList[0] := DEFAULT_VEC3F;
// Or via a pointer...
VecList[1] := @DEFAULT_VEC3F;
// And directly assign *from* the list to a pointer...
PVec := VecList[0];
with PVec^ do begin
X := 2.0;
Y := 4.0;
Z := 6.0;
end;
with PVec^ do
WriteLn(Format('[%f %f %f]', [X, Y, Z]));
// Or just do this
with VecList[0].V^ do begin
X := 2.0;
Y := 4.0;
Z := 6.0;
end;
//And this
with VecList[0].V^ do
WriteLn(Format('[%f %f %f]', [X, Y, Z]));
end.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20190708/e35cc5a0/attachment.html>
More information about the fpc-devel
mailing list