Data Types
This commit is contained in:
@@ -7,20 +7,8 @@ uses
|
||||
Myc.Data.Types;
|
||||
|
||||
type
|
||||
// Implements the simple tuple data value.
|
||||
TImplDataTupleValue = class(TInterfacedObject, IDataValue, IDataTupleValue)
|
||||
private
|
||||
FItems: TArray<IDataValue>;
|
||||
function GetDataType: IDataType;
|
||||
function GetAsString: string;
|
||||
function GetItemCount: Integer;
|
||||
function GetItem(Idx: Integer): IDataValue;
|
||||
public
|
||||
constructor Create(const AItems: array of IDataValue);
|
||||
end;
|
||||
|
||||
// Implements the singleton tuple data type.
|
||||
TImplDataTupleType = class(TInterfacedObject, IDataType, IDataTupleType)
|
||||
TDataTupleType = class(TInterfacedObject, IDataType, IDataTupleType)
|
||||
strict private
|
||||
class var
|
||||
FSingleton: IDataTupleType;
|
||||
@@ -35,9 +23,97 @@ type
|
||||
|
||||
implementation
|
||||
|
||||
{ TImplDataTupleValue }
|
||||
type
|
||||
// Implements the simple tuple data value.
|
||||
TDataTupleValue = class(TInterfacedObject, IDataValue, IDataTupleValue)
|
||||
private
|
||||
FItems: TArray<IDataValue>;
|
||||
function GetDataType: IDataType;
|
||||
function GetAsString: string;
|
||||
function GetItemCount: Integer;
|
||||
function GetItem(Idx: Integer): IDataValue;
|
||||
public
|
||||
constructor Create(const AItems: array of IDataValue);
|
||||
end;
|
||||
|
||||
constructor TImplDataTupleValue.Create(const AItems: array of IDataValue);
|
||||
// Optimized singleton implementation for a tuple with 0 elements.
|
||||
TDataTupleValue0 = class(TInterfacedObject, IDataValue, IDataTupleValue)
|
||||
strict private
|
||||
class var
|
||||
FSingleton: IDataTupleValue;
|
||||
class constructor CreateClass;
|
||||
private
|
||||
function GetDataType: IDataType;
|
||||
function GetAsString: string;
|
||||
function GetItemCount: Integer;
|
||||
function GetItem(Idx: Integer): IDataValue;
|
||||
public
|
||||
class property Singleton: IDataTupleValue read FSingleton;
|
||||
end;
|
||||
|
||||
// Optimized implementation for a tuple with 1 element.
|
||||
TDataTupleValue1 = class(TInterfacedObject, IDataValue, IDataTupleValue)
|
||||
private
|
||||
FItem0: IDataValue;
|
||||
function GetDataType: IDataType;
|
||||
function GetAsString: string;
|
||||
function GetItemCount: Integer;
|
||||
function GetItem(Idx: Integer): IDataValue;
|
||||
public
|
||||
constructor Create(const AItems: array of IDataValue);
|
||||
end;
|
||||
|
||||
// Optimized implementation for a tuple with 2 elements.
|
||||
TDataTupleValue2 = class(TInterfacedObject, IDataValue, IDataTupleValue)
|
||||
private
|
||||
FItem0, FItem1: IDataValue;
|
||||
function GetDataType: IDataType;
|
||||
function GetAsString: string;
|
||||
function GetItemCount: Integer;
|
||||
function GetItem(Idx: Integer): IDataValue;
|
||||
public
|
||||
constructor Create(const AItems: array of IDataValue);
|
||||
end;
|
||||
|
||||
// Optimized implementation for a tuple with 3 elements.
|
||||
TDataTupleValue3 = class(TInterfacedObject, IDataValue, IDataTupleValue)
|
||||
private
|
||||
FItem0, FItem1, FItem2: IDataValue;
|
||||
function GetDataType: IDataType;
|
||||
function GetAsString: string;
|
||||
function GetItemCount: Integer;
|
||||
function GetItem(Idx: Integer): IDataValue;
|
||||
public
|
||||
constructor Create(const AItems: array of IDataValue);
|
||||
end;
|
||||
|
||||
// Optimized implementation for a tuple with 4 elements.
|
||||
TDataTupleValue4 = class(TInterfacedObject, IDataValue, IDataTupleValue)
|
||||
private
|
||||
FItem0, FItem1, FItem2, FItem3: IDataValue;
|
||||
function GetDataType: IDataType;
|
||||
function GetAsString: string;
|
||||
function GetItemCount: Integer;
|
||||
function GetItem(Idx: Integer): IDataValue;
|
||||
public
|
||||
constructor Create(const AItems: array of IDataValue);
|
||||
end;
|
||||
|
||||
// Optimized implementation for a tuple with 5 elements.
|
||||
TDataTupleValue5 = class(TInterfacedObject, IDataValue, IDataTupleValue)
|
||||
private
|
||||
FItem0, FItem1, FItem2, FItem3, FItem4: IDataValue;
|
||||
function GetDataType: IDataType;
|
||||
function GetAsString: string;
|
||||
function GetItemCount: Integer;
|
||||
function GetItem(Idx: Integer): IDataValue;
|
||||
public
|
||||
constructor Create(const AItems: array of IDataValue);
|
||||
end;
|
||||
|
||||
{ TDataTupleValue (generic implementation for N > 5 elements) }
|
||||
|
||||
constructor TDataTupleValue.Create(const AItems: array of IDataValue);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
@@ -47,12 +123,12 @@ begin
|
||||
FItems[i] := AItems[i];
|
||||
end;
|
||||
|
||||
function TImplDataTupleValue.GetDataType: IDataType;
|
||||
function TDataTupleValue.GetDataType: IDataType;
|
||||
begin
|
||||
Result := TImplDataTupleType.Singleton;
|
||||
Result := TDataTupleType.Singleton;
|
||||
end;
|
||||
|
||||
function TImplDataTupleValue.GetAsString: string;
|
||||
function TDataTupleValue.GetAsString: string;
|
||||
var
|
||||
sb: TStringBuilder;
|
||||
i: Integer;
|
||||
@@ -73,34 +149,300 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TImplDataTupleValue.GetItem(Idx: Integer): IDataValue;
|
||||
function TDataTupleValue.GetItem(Idx: Integer): IDataValue;
|
||||
begin
|
||||
Result := FItems[Idx];
|
||||
end;
|
||||
|
||||
function TImplDataTupleValue.GetItemCount: Integer;
|
||||
function TDataTupleValue.GetItemCount: Integer;
|
||||
begin
|
||||
Result := Length(FItems);
|
||||
end;
|
||||
|
||||
{ TImplDataTupleType }
|
||||
{ TDataTupleValue0 }
|
||||
|
||||
class constructor TImplDataTupleType.CreateClass;
|
||||
class constructor TDataTupleValue0.CreateClass;
|
||||
begin
|
||||
FSingleton := TImplDataTupleType.Create;
|
||||
FSingleton := TDataTupleValue0.Create;
|
||||
end;
|
||||
|
||||
function TImplDataTupleType.CreateValue(const AItems: array of IDataValue): IDataTupleValue;
|
||||
function TDataTupleValue0.GetAsString: string;
|
||||
begin
|
||||
Result := TImplDataTupleValue.Create(AItems);
|
||||
Result := '()';
|
||||
end;
|
||||
|
||||
function TImplDataTupleType.GetName: String;
|
||||
function TDataTupleValue0.GetDataType: IDataType;
|
||||
begin
|
||||
Result := TDataTupleType.Singleton;
|
||||
end;
|
||||
|
||||
function TDataTupleValue0.GetItem(Idx: Integer): IDataValue;
|
||||
begin
|
||||
raise EArgumentException.Create('Index out of bounds');
|
||||
end;
|
||||
|
||||
function TDataTupleValue0.GetItemCount: Integer;
|
||||
begin
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
{ TDataTupleValue1 }
|
||||
|
||||
constructor TDataTupleValue1.Create(const AItems: array of IDataValue);
|
||||
begin
|
||||
inherited Create;
|
||||
FItem0 := AItems[0];
|
||||
end;
|
||||
|
||||
function TDataTupleValue1.GetAsString: string;
|
||||
begin
|
||||
Result := '(' + FItem0.AsString + ')';
|
||||
end;
|
||||
|
||||
function TDataTupleValue1.GetDataType: IDataType;
|
||||
begin
|
||||
Result := TDataTupleType.Singleton;
|
||||
end;
|
||||
|
||||
function TDataTupleValue1.GetItem(Idx: Integer): IDataValue;
|
||||
begin
|
||||
case Idx of
|
||||
0: Result := FItem0;
|
||||
else
|
||||
raise EArgumentException.Create('Index out of bounds');
|
||||
end;
|
||||
end;
|
||||
|
||||
function TDataTupleValue1.GetItemCount: Integer;
|
||||
begin
|
||||
Result := 1;
|
||||
end;
|
||||
|
||||
{ TDataTupleValue2 }
|
||||
|
||||
constructor TDataTupleValue2.Create(const AItems: array of IDataValue);
|
||||
begin
|
||||
inherited Create;
|
||||
FItem0 := AItems[0];
|
||||
FItem1 := AItems[1];
|
||||
end;
|
||||
|
||||
function TDataTupleValue2.GetAsString: string;
|
||||
begin
|
||||
Result := '(' + FItem0.AsString + ', ' + FItem1.AsString + ')';
|
||||
end;
|
||||
|
||||
function TDataTupleValue2.GetDataType: IDataType;
|
||||
begin
|
||||
Result := TDataTupleType.Singleton;
|
||||
end;
|
||||
|
||||
function TDataTupleValue2.GetItem(Idx: Integer): IDataValue;
|
||||
begin
|
||||
case Idx of
|
||||
0: Result := FItem0;
|
||||
1: Result := FItem1;
|
||||
else
|
||||
raise EArgumentException.Create('Index out of bounds');
|
||||
end;
|
||||
end;
|
||||
|
||||
function TDataTupleValue2.GetItemCount: Integer;
|
||||
begin
|
||||
Result := 2;
|
||||
end;
|
||||
|
||||
{ TDataTupleValue3 }
|
||||
|
||||
constructor TDataTupleValue3.Create(const AItems: array of IDataValue);
|
||||
begin
|
||||
inherited Create;
|
||||
FItem0 := AItems[0];
|
||||
FItem1 := AItems[1];
|
||||
FItem2 := AItems[2];
|
||||
end;
|
||||
|
||||
function TDataTupleValue3.GetAsString: string;
|
||||
var
|
||||
sb: TStringBuilder;
|
||||
begin
|
||||
sb := TStringBuilder.Create;
|
||||
try
|
||||
sb.Append('(');
|
||||
sb.Append(FItem0.AsString);
|
||||
sb.Append(', ');
|
||||
sb.Append(FItem1.AsString);
|
||||
sb.Append(', ');
|
||||
sb.Append(FItem2.AsString);
|
||||
sb.Append(')');
|
||||
Result := sb.ToString;
|
||||
finally
|
||||
sb.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TDataTupleValue3.GetDataType: IDataType;
|
||||
begin
|
||||
Result := TDataTupleType.Singleton;
|
||||
end;
|
||||
|
||||
function TDataTupleValue3.GetItem(Idx: Integer): IDataValue;
|
||||
begin
|
||||
case Idx of
|
||||
0: Result := FItem0;
|
||||
1: Result := FItem1;
|
||||
2: Result := FItem2;
|
||||
else
|
||||
raise EArgumentException.Create('Index out of bounds');
|
||||
end;
|
||||
end;
|
||||
|
||||
function TDataTupleValue3.GetItemCount: Integer;
|
||||
begin
|
||||
Result := 3;
|
||||
end;
|
||||
|
||||
{ TDataTupleValue4 }
|
||||
|
||||
constructor TDataTupleValue4.Create(const AItems: array of IDataValue);
|
||||
begin
|
||||
inherited Create;
|
||||
FItem0 := AItems[0];
|
||||
FItem1 := AItems[1];
|
||||
FItem2 := AItems[2];
|
||||
FItem3 := AItems[3];
|
||||
end;
|
||||
|
||||
function TDataTupleValue4.GetAsString: string;
|
||||
var
|
||||
sb: TStringBuilder;
|
||||
begin
|
||||
sb := TStringBuilder.Create;
|
||||
try
|
||||
sb.Append('(');
|
||||
sb.Append(FItem0.AsString);
|
||||
sb.Append(', ');
|
||||
sb.Append(FItem1.AsString);
|
||||
sb.Append(', ');
|
||||
sb.Append(FItem2.AsString);
|
||||
sb.Append(', ');
|
||||
sb.Append(FItem3.AsString);
|
||||
sb.Append(')');
|
||||
Result := sb.ToString;
|
||||
finally
|
||||
sb.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TDataTupleValue4.GetDataType: IDataType;
|
||||
begin
|
||||
Result := TDataTupleType.Singleton;
|
||||
end;
|
||||
|
||||
function TDataTupleValue4.GetItem(Idx: Integer): IDataValue;
|
||||
begin
|
||||
case Idx of
|
||||
0: Result := FItem0;
|
||||
1: Result := FItem1;
|
||||
2: Result := FItem2;
|
||||
3: Result := FItem3;
|
||||
else
|
||||
raise EArgumentException.Create('Index out of bounds');
|
||||
end;
|
||||
end;
|
||||
|
||||
function TDataTupleValue4.GetItemCount: Integer;
|
||||
begin
|
||||
Result := 4;
|
||||
end;
|
||||
|
||||
{ TDataTupleValue5 }
|
||||
|
||||
constructor TDataTupleValue5.Create(const AItems: array of IDataValue);
|
||||
begin
|
||||
inherited Create;
|
||||
FItem0 := AItems[0];
|
||||
FItem1 := AItems[1];
|
||||
FItem2 := AItems[2];
|
||||
FItem3 := AItems[3];
|
||||
FItem4 := AItems[4];
|
||||
end;
|
||||
|
||||
function TDataTupleValue5.GetAsString: string;
|
||||
var
|
||||
sb: TStringBuilder;
|
||||
begin
|
||||
sb := TStringBuilder.Create;
|
||||
try
|
||||
sb.Append('(');
|
||||
sb.Append(FItem0.AsString);
|
||||
sb.Append(', ');
|
||||
sb.Append(FItem1.AsString);
|
||||
sb.Append(', ');
|
||||
sb.Append(FItem2.AsString);
|
||||
sb.Append(', ');
|
||||
sb.Append(FItem3.AsString);
|
||||
sb.Append(', ');
|
||||
sb.Append(FItem4.AsString);
|
||||
sb.Append(')');
|
||||
Result := sb.ToString;
|
||||
finally
|
||||
sb.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TDataTupleValue5.GetDataType: IDataType;
|
||||
begin
|
||||
Result := TDataTupleType.Singleton;
|
||||
end;
|
||||
|
||||
function TDataTupleValue5.GetItem(Idx: Integer): IDataValue;
|
||||
begin
|
||||
case Idx of
|
||||
0: Result := FItem0;
|
||||
1: Result := FItem1;
|
||||
2: Result := FItem2;
|
||||
3: Result := FItem3;
|
||||
4: Result := FItem4;
|
||||
else
|
||||
raise EArgumentException.Create('Index out of bounds');
|
||||
end;
|
||||
end;
|
||||
|
||||
function TDataTupleValue5.GetItemCount: Integer;
|
||||
begin
|
||||
Result := 5;
|
||||
end;
|
||||
|
||||
{ TDataTupleType }
|
||||
|
||||
class constructor TDataTupleType.CreateClass;
|
||||
begin
|
||||
FSingleton := TDataTupleType.Create;
|
||||
end;
|
||||
|
||||
function TDataTupleType.CreateValue(const AItems: array of IDataValue): IDataTupleValue;
|
||||
begin
|
||||
// Use optimized implementations for tuples with 0 to 5 elements.
|
||||
case Length(AItems) of
|
||||
0: Result := TDataTupleValue0.Singleton;
|
||||
1: Result := TDataTupleValue1.Create(AItems);
|
||||
2: Result := TDataTupleValue2.Create(AItems);
|
||||
3: Result := TDataTupleValue3.Create(AItems);
|
||||
4: Result := TDataTupleValue4.Create(AItems);
|
||||
5: Result := TDataTupleValue5.Create(AItems);
|
||||
else
|
||||
// Use the generic implementation for tuples with more than 5 elements.
|
||||
Result := TDataTupleValue.Create(AItems);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TDataTupleType.GetName: String;
|
||||
begin
|
||||
Result := 'Tuple';
|
||||
end;
|
||||
|
||||
function TImplDataTupleType.GetKind: TDataKind;
|
||||
function TDataTupleType.GetKind: TDataKind;
|
||||
begin
|
||||
Result := dkTuple;
|
||||
end;
|
||||
|
||||
Reference in New Issue
Block a user