program ImmutableArray;
{$APPTYPE CONSOLE}
uses
Generics.Defaults,
SysUtils;
type
TImmutableArray<T> = record
strict private
fData: TArray<T>;
function IndexOf(const value: T): Integer;
public
class operator Implicit(const data: TArray<T>): TImmutableArray<T>; inline;
function Add(const value: T): TArray<T>;
function Remove(const value: T): TArray<T>;
property Data: TArray<T> read fData;
end;
{ TImmutableArray<T> }
class operator TImmutableArray<T>.Implicit(
const data: TArray<T>): TImmutableArray<T>;
begin
Result.fData := data;
end;
function TImmutableArray<T>.Add(const value: T): TArray<T>;
var
len: Integer;
begin
Result := fData;
len := Length(Result);
SetLength(Result, len + 1);
Result[len] := value;
end;
function TImmutableArray<T>.Remove(const value: T): TArray<T>;
var
i, n: Integer;
begin
i := IndexOf(value);
if i < 0 then
Exit(fData);
n := High(fData);
if n = 0 then
Exit(nil);
if i = n then
Exit(Copy(fData, 0, i));
Result := Copy(fData);
Result[i] := Default(T);
Move(Result[i + 1], Result[i], (n - i) * SizeOf(T));
SetLength(Result, n);
end;
function TImmutableArray<T>.IndexOf(const value: T): Integer;
var
i: Integer;
comparer: IEqualityComparer<T>;
begin
comparer := TEqualityComparer<T>.Default;
for i := 0 to High(fData) do
if comparer.Equals(fData[i], value) then
Exit(i);
Result := -1;
end;
procedure Main;
var
a, b, c: TImmutableArray<Integer>;
i: Integer;
begin
a := TArray<Integer>.Create(1, 2, 3, 4);
b := a;
c := a.Add(5);
a := TArray<Integer>.Create(1, 2);
c := a.Remove(2);
b := c.Remove(1);
for i in a.Data do
Writeln(i);
end;
begin
try
Main;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.
Comments (0)
HTTPSSSH
You can clone a snippet to your computer for local editing.
Learn more.