On Fri, Feb 22, 2019 at 1:07 AM Paul van Helden <p...@planetgis.co.za> wrote:
> How do you make a (for in) enumerator with a record? I don't use them for > exactly this reason, and they did seem to be another useful language > feature that turned out to be poorly implemented by Embarcadero. (Haven't > checked with FPC). > Here's an example (for FPC) that demonstrates it by implementing the "take-while" pattern: program TakeWhileExample; {$mode Delphi}{$H+}{$J-} {$modeswitch NestedProcVars} {$ImplicitExceptions Off} {$PointerMath On} type TSlice<T> = record public type PT = ^T; ArrayType = array of T; private FFirst, FLast, FCurrent: PT; function GetCurrent: T; inline; public function GetEnumerator: TSlice<T>; inline; function MoveNext: Boolean; inline; class function TakeWhile(const A: ArrayType; function F(const Val: T): Boolean): TSlice<T>; static; inline; property Current: T read GetCurrent; end; TTestFunc<T> = function(const Val: T): Boolean; function TSlice<T>.GetCurrent: T; begin Result := FCurrent^; end; function TSlice<T>.GetEnumerator: TSlice<T>; begin Result := Self; with Result do FCurrent := FFirst - 1; end; function TSlice<T>.MoveNext: Boolean; begin Inc(FCurrent); Exit((FCurrent <= FLast) and (FFirst <> FLast)); end; function Test(const Val: SizeUInt): Boolean; inline; begin Exit((Val < 50000000)); end; class function TSlice<T>.TakeWhile(const A: ArrayType; function F(const Val: T): Boolean): TSlice<T>; var I: SizeUInt; X: TTestFunc<T> absolute F; //FPC generates slightly better code for the "absolute" way, not sure why... begin with Result do begin FFirst := @A[0]; FLast := @A[0]; for I := 0 to High(A) do case X(A[I]) of True: Inc(FLast); False: Exit(); end; end; end; var I, J: SizeUInt; Arr: TSlice<SizeUInt>.ArrayType; begin SetLength(Arr, 100000000); for I := 0 to 99999999 do Arr[I] := I; I := 0; J := 0; for I in TSlice<SizeUInt>.TakeWhile(Arr, Test) do J := I; WriteLn(J); end.
_______________________________________________ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel