Extended records can have an enumerator. To this end, a function returning an enumerator record must be defined in the extended record:
{$mode objfpc} {$modeswitch advancedrecords} type TIntArray = array[0..3] of Integer; TEnumerator = record private FIndex: Integer; FArray: TIntArray; function GetCurrent: Integer; public function MoveNext: Boolean; property Current: Integer read GetCurrent; end; TMyArray = record F: array[0..3] of Integer; function GetEnumerator: TEnumerator; end; function TEnumerator.MoveNext: Boolean; begin inc(FIndex); Result := FIndex < Length(FArray); end; function TEnumerator.GetCurrent: Integer; begin Result := FArray[FIndex]; end; function TMyArray.GetEnumerator: TEnumerator; begin Result.FArray := F; Result.FIndex := -1; end;
After these definitions, the following code will compile and enumerate all elements in F:
var Arr: TMyArray; I: Integer; begin for I in Arr do WriteLn(I); end.
The same effect can be achieved with the enumerator operator:
{$mode objfpc} {$modeswitch advancedrecords} type TIntArray = array[0..3] of Integer; TEnumerator = record private FIndex: Integer; FArray: TIntArray; function GetCurrent: Integer; public function MoveNext: Boolean; property Current: Integer read GetCurrent; end; TMyArray = record F: array[0..3] of Integer; end; function TEnumerator.MoveNext: Boolean; begin inc(FIndex); Result := FIndex < Length(FArray); end; function TEnumerator.GetCurrent: Integer; begin Result := FArray[FIndex]; end; operator Enumerator(const A: TMyArray): TEnumerator; begin Result.FArray := A.F; Result.FIndex := -1; end;
This will allow the code to run as well.