TRange

Python の yield が恋しい.

unit MyUtils.Range;

interface

uses
  Generics.Collections;

type
  TRange = record
  strict private
    FStartIndex: Integer;
    FEndIndex: Integer;
  public
    constructor Create(StartIndex, EndIndex: Integer);
    type
      TEnumerator = class(TEnumerator<Integer>)
      private
        FIndex: Integer;
        FStartIndex: Integer;
        FEndIndex: Integer;
        function GetCurrent: Integer;
      protected
        function DoGetCurrent: Integer; override;
        function DoMoveNext: Boolean; override;
      public
        constructor Create(StartIndex, EndIndex: Integer);
        property Current: Integer read GetCurrent;
        function MoveNext: Boolean;
      end;

    function GetEnumerator: TEnumerator;
  end;

  function Range(StartIndex, EndIndex: Integer): TRange;

implementation

function Range(StartIndex, EndIndex: Integer): TRange;
begin
  Result := TRange.Create(StartIndex, EndIndex);
end;

{ TRange }

constructor TRange.Create(StartIndex, EndIndex: Integer);
begin
  FStartIndex := StartIndex;
  FEndIndex := EndIndex;
end;

function TRange.GetEnumerator: TEnumerator;
begin
  Result := TEnumerator.Create(FStartIndex, FEndIndex);
end;

{ TRange.TEnumerator }

constructor TRange.TEnumerator.Create(StartIndex, EndIndex: Integer);
begin
  inherited Create;
  FStartIndex := StartIndex;
  FEndIndex := EndIndex;
  FIndex := StartIndex - 1;
end;

function TRange.TEnumerator.DoGetCurrent: Integer;
begin
  Result := GetCurrent;
end;

function TRange.TEnumerator.DoMoveNext: Boolean;
begin
  Result := MoveNext;
end;

function TRange.TEnumerator.GetCurrent: Integer;
begin
  Result := FIndex;
end;

function TRange.TEnumerator.MoveNext: Boolean;
begin
  Inc(FIndex);
  Result := FIndex <= FEndIndex;
end;

end.