<div dir="ltr"><div dir="ltr"><div dir="ltr">On Fri, Feb 22, 2019 at 1:07 AM Paul van Helden <<a href="mailto:paul@planetgis.co.za">paul@planetgis.co.za</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><div> 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).</div></div></div></blockquote><div><br></div><div>Here's an example (for FPC) that demonstrates it by implementing the "take-while" pattern:</div><div><br></div><div>program TakeWhileExample;</div><div><br></div><div>{$mode Delphi}{$H+}{$J-}</div><div>{$modeswitch NestedProcVars}</div><div>{$ImplicitExceptions Off}</div><div>{$PointerMath On}</div><div><br></div><div>type</div><div>  TSlice<T> = record</div><div>  public type</div><div>    PT = ^T;</div><div>    ArrayType = array of T;</div><div>  private</div><div>    FFirst, FLast, FCurrent: PT;</div><div>    function GetCurrent: T; inline;</div><div>  public</div><div>    function GetEnumerator: TSlice<T>; inline;</div><div>    function MoveNext: Boolean; inline;</div><div>    class function TakeWhile(const A: ArrayType; function F(const Val: T): Boolean): TSlice<T>; static; inline;</div><div>    property Current: T read GetCurrent;</div><div>  end;</div><div><br></div><div>  TTestFunc<T> = function(const Val: T): Boolean;</div><div><br></div><div>  function TSlice<T>.GetCurrent: T;</div><div>  begin</div><div>    Result := FCurrent^;</div><div>  end;</div><div><br></div><div>  function TSlice<T>.GetEnumerator: TSlice<T>;</div><div>  begin</div><div>    Result := Self;</div><div>    with Result do FCurrent := FFirst - 1;</div><div>  end;</div><div><br></div><div>  function TSlice<T>.MoveNext: Boolean;</div><div>  begin</div><div>    Inc(FCurrent);</div><div>    Exit((FCurrent <= FLast) and (FFirst <> FLast));</div><div>  end;</div><div><br></div><div>  function Test(const Val: SizeUInt): Boolean; inline;</div><div>  begin</div><div>    Exit((Val < 50000000));</div><div>  end;</div><div><br></div><div>  class function TSlice<T>.TakeWhile(const A: ArrayType; function F(const Val: T): Boolean): TSlice<T>;</div><div>  var</div><div>    I: SizeUInt;</div><div>    X: TTestFunc<T> absolute F;</div><div>    //FPC generates slightly better code for the "absolute" way, not sure why...</div><div>  begin</div><div>    with Result do begin</div><div>      FFirst := @A[0];</div><div>      FLast := @A[0];</div><div>      for I := 0 to High(A) do</div><div>        case X(A[I]) of</div><div>          True: Inc(FLast);</div><div>          False: Exit();</div><div>        end;</div><div>    end;</div><div>  end;</div><div><br></div><div>var</div><div>  I, J: SizeUInt;</div><div>  Arr: TSlice<SizeUInt>.ArrayType;</div><div><br></div><div>begin</div><div>  SetLength(Arr, 100000000);</div><div>  for I := 0 to 99999999 do Arr[I] := I;</div><div>  I := 0;</div><div>  J := 0;</div><div>  for I in TSlice<SizeUInt>.TakeWhile(Arr, Test) do J := I;</div><div>  WriteLn(J);</div><div>end. </div></div></div></div>