[fpc-pascal] For ..in GetEnumerator Allocation
Mattias Gaertner
nc-gaertnma at netcologne.de
Wed Oct 4 17:26:12 CEST 2017
On Wed, 4 Oct 2017 15:41:27 +0700
Ryan Joseph <ryan at thealchemistguild.com> wrote:
> As I understand the for..in loop GetEnumerator method is expected to create a new object each time it’s called and FPC destroys it later when the loos is finished. Can I retain the enumerator and just reset it in-between calls? I’d like to remove all these alloc/deallocs so I can use for..in more efficiently in tight loops.
Here is an example how to use a global enumerator object:
type
TMyEnumerator = class
private
FOwner: TComponent;
FCurrent: TComponent;
public
procedure Init(Owner: TComponent);
function MoveNext: boolean;
property Current: TComponent read FCurrent;
function GetEnumerator: TMyEnumerator;
end;
TForm1 = class(TForm)
public
function GetEnumerator: TMyEnumerator;
end;
var
Form2: TForm2;
MyEnumerator: TMyEnumerator;
implementation
procedure TMyEnumerator.Init(Owner: TComponent);
begin
FOwner:=Owner;
FCurrent:=nil;
end;
function TMyEnumerator.MoveNext: boolean;
var
i: Integer;
begin
if FCurrent=nil then begin
if FOwner.ComponentCount=0 then exit(false);
FCurrent:=FOwner.Components[0];
end else begin
i:=FCurrent.ComponentIndex+1;
if i>=FCurrent.Owner.ComponentCount then exit(false);
FCurrent:=FCurrent.Owner.Components[i];
end;
Result:=true;
end;
function TMyEnumerator.GetEnumerator: TMyEnumerator;
begin
Result:=Self;
end;
function TForm1.GetEnumerator: TMyEnumerator;
begin
if MyEnumerator=nil then
MyEnumerator:=TMyEnumerator.Create;
MyEnumerator.Init(Self);
end;
finalization
MyEnumerator.Free;
end.
More information about the fpc-pascal
mailing list