Last active
September 5, 2017 14:26
-
-
Save superswanman/abf73da43e99e60056a89d978d151567 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
unit Lyna.Generators; | |
interface | |
uses | |
SysUtils, Rtti, TypInfo; | |
type | |
TRange = record | |
strict private | |
FStart, FStep, FLen: Integer; | |
public | |
constructor Create(AStart, AEnd, AStep: Integer); | |
function Reverse: TRange; inline; | |
function ToArray: TArray<Integer>; | |
type | |
TEnumerator = class | |
private | |
FStart, FStep, FLen, FCurrent: Integer; | |
function GetCurrent: Integer; | |
public | |
constructor Create(AStart, AStep, ALen: Integer); | |
function MoveNext: Boolean; inline; | |
property Current: Integer read GetCurrent; | |
end; | |
function GetEnumerator: TEnumerator; | |
end; | |
function Range(ACount: Integer): TRange; overload; | |
function Range(AStart, AEnd: Integer): TRange; overload; | |
function Range(AStart, AEnd, AStep: Integer): TRange; overload; | |
implementation | |
function Range(ACount: Integer): TRange; | |
begin | |
Result := TRange.Create(0, ACount-1, 1); | |
end; | |
function Range(AStart, AEnd: Integer): TRange; | |
begin | |
Result := TRange.Create(AStart, AEnd, 1); | |
end; | |
function Range(AStart, AEnd, AStep: Integer): TRange; | |
begin | |
Result := TRange.Create(AStart,AEnd, AStep); | |
end; | |
function GetLength(AStart, AEnd, AStep: Integer): Integer; | |
begin | |
Result := 0; | |
if AStart < AEnd then | |
begin | |
Result := (AEnd-AStart) div AStep + 1; | |
end; | |
end; | |
{ TRange } | |
constructor TRange.Create(AStart, AEnd, AStep: Integer); | |
begin | |
FStart := AStart; | |
FStep := AStep; | |
if FStep > 0 then | |
FLen := GetLength(FStart, AEnd, FStep) | |
else if FStep < 0 then | |
FLen := GetLength(AEnd, FStart, -FStep) | |
else | |
FLen := 0; | |
end; | |
function TRange.Reverse: TRange; | |
begin | |
FStart := FStart + (FLen-1) * FStep; | |
FStep := -FStep; | |
Result := Self; | |
end; | |
function TRange.ToArray: TArray<Integer>; | |
var | |
i, value: Integer; | |
begin | |
SetLength(Result, FLen); | |
i := 0; | |
for value in Self do | |
begin | |
Result[i] := value; | |
Inc(i); | |
end; | |
end; | |
function TRange.GetEnumerator: TEnumerator; | |
begin | |
Result := TRange.TEnumerator.Create(FStart, FStep, FLen); | |
end; | |
{ TRange.TEnumerator } | |
constructor TRange.TEnumerator.Create(AStart, AStep, ALen: Integer); | |
begin | |
FStart := AStart; | |
FStep := AStep; | |
FLen := ALen; | |
FCurrent := -1; | |
end; | |
function TRange.TEnumerator.GetCurrent: Integer; | |
begin | |
Result := FStart + FCurrent * FStep; | |
end; | |
function TRange.TEnumerator.MoveNext: Boolean; | |
begin | |
Inc(FCurrent); | |
Result := FCurrent < FLen; | |
end; | |
end. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment