On Wed, 4 Oct 2017 15:41:27 +0700
Ryan Joseph <r...@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.
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to