201 lines
5.0 KiB
ObjectPascal
201 lines
5.0 KiB
ObjectPascal
unit Myc.Data.Types.Tuple;
|
|
|
|
interface
|
|
|
|
uses
|
|
System.SysUtils,
|
|
Myc.Data.Types;
|
|
|
|
type
|
|
// An interface helper for the singleton IDataTupleType.
|
|
TTupleType = record
|
|
private
|
|
FTupleType: IDataTupleType;
|
|
function GetName: String; inline;
|
|
public
|
|
constructor Create(const ATupleType: IDataTupleType);
|
|
class operator Implicit(const A: IDataTupleType): TTupleType; overload;
|
|
class operator Implicit(const A: TTupleType): IDataTupleType; overload;
|
|
property Name: String read GetName;
|
|
end;
|
|
|
|
// An interface helper for IDataTupleValue.
|
|
TTupleValue = record
|
|
private
|
|
FTupleValue: IDataTupleValue;
|
|
function GetItem(Idx: Integer): TDataValue; inline;
|
|
function GetItemCount: Integer; inline;
|
|
public
|
|
constructor Create(const ATupleValue: IDataTupleValue);
|
|
|
|
class operator Implicit(const A: IDataTupleValue): TTupleValue; overload;
|
|
class operator Implicit(const A: TTupleValue): IDataTupleValue; overload;
|
|
|
|
property ItemCount: Integer read GetItemCount;
|
|
property Items[Idx: Integer]: TDataValue read GetItem; default;
|
|
end;
|
|
|
|
TDataValueHelper = record helper for TDataValue
|
|
public
|
|
function AsTuple: TTupleValue;
|
|
end;
|
|
|
|
TDataTypeHelper = record helper for TDataType
|
|
public
|
|
function AsTuple: TTupleType;
|
|
end;
|
|
|
|
// Public factory for creating simple, non-cached tuple values.
|
|
TTuple = record
|
|
public
|
|
class function Create(const AItems: array of IDataValue): IDataTupleValue; static;
|
|
end;
|
|
|
|
implementation
|
|
|
|
type
|
|
// Implements the simple tuple data value.
|
|
TImplDataTupleValue = class(TInterfacedObject, IDataValue, IDataTupleValue)
|
|
private
|
|
FItems: TArray<IDataValue>;
|
|
function GetDataType: IDataType;
|
|
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)
|
|
strict private
|
|
class var
|
|
FSingleton: IDataTupleType;
|
|
class constructor CreateClass;
|
|
private
|
|
function GetName: String;
|
|
public
|
|
class property Singleton: IDataTupleType read FSingleton;
|
|
end;
|
|
|
|
{ TTupleValue }
|
|
|
|
constructor TTupleValue.Create(const ATupleValue: IDataTupleValue);
|
|
begin
|
|
FTupleValue := ATupleValue;
|
|
end;
|
|
|
|
function TTupleValue.GetItem(Idx: Integer): TDataValue;
|
|
begin
|
|
if Assigned(FTupleValue) then
|
|
Result := FTupleValue.Items[Idx]
|
|
else
|
|
Result := TDataValue.Create(nil);
|
|
end;
|
|
|
|
function TTupleValue.GetItemCount: Integer;
|
|
begin
|
|
if Assigned(FTupleValue) then
|
|
Result := FTupleValue.ItemCount
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
class operator TTupleValue.Implicit(const A: TTupleValue): IDataTupleValue;
|
|
begin
|
|
Result := A.FTupleValue;
|
|
end;
|
|
|
|
class operator TTupleValue.Implicit(const A: IDataTupleValue): TTupleValue;
|
|
begin
|
|
Result.FTupleValue := A;
|
|
end;
|
|
|
|
{ TTupleType }
|
|
|
|
constructor TTupleType.Create(const ATupleType: IDataTupleType);
|
|
begin
|
|
FTupleType := ATupleType;
|
|
end;
|
|
|
|
function TTupleType.GetName: String;
|
|
begin
|
|
if Assigned(FTupleType) then
|
|
Result := FTupleType.Name
|
|
else
|
|
Result := '';
|
|
end;
|
|
|
|
class operator TTupleType.Implicit(const A: TTupleType): IDataTupleType;
|
|
begin
|
|
Result := A.FTupleType;
|
|
end;
|
|
|
|
class operator TTupleType.Implicit(const A: IDataTupleType): TTupleType;
|
|
begin
|
|
Result.FTupleType := A;
|
|
end;
|
|
|
|
{ TImplDataTupleValue }
|
|
|
|
constructor TImplDataTupleValue.Create(const AItems: array of IDataValue);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
inherited Create;
|
|
SetLength(FItems, Length(AItems));
|
|
for i := 0 to High(AItems) do
|
|
FItems[i] := AItems[i];
|
|
end;
|
|
|
|
function TImplDataTupleValue.GetDataType: IDataType;
|
|
begin
|
|
Result := TImplDataTupleType.Singleton;
|
|
end;
|
|
|
|
function TImplDataTupleValue.GetItem(Idx: Integer): IDataValue;
|
|
begin
|
|
Result := FItems[Idx];
|
|
end;
|
|
|
|
function TImplDataTupleValue.GetItemCount: Integer;
|
|
begin
|
|
Result := Length(FItems);
|
|
end;
|
|
|
|
{ TImplDataTupleType }
|
|
|
|
class constructor TImplDataTupleType.CreateClass;
|
|
begin
|
|
FSingleton := TImplDataTupleType.Create;
|
|
end;
|
|
|
|
function TImplDataTupleType.GetName: String;
|
|
begin
|
|
Result := 'Tuple';
|
|
end;
|
|
|
|
{ TDataValueHelper }
|
|
|
|
function TDataValueHelper.AsTuple: TTupleValue;
|
|
begin
|
|
Result := Self.DataValue as IDataTupleValue;
|
|
end;
|
|
|
|
{ TDataTypeHelper }
|
|
|
|
function TDataTypeHelper.AsTuple: TTupleType;
|
|
begin
|
|
Result := Self.DataType as IDataTupleType;
|
|
end;
|
|
|
|
{ TTuple }
|
|
|
|
class function TTuple.Create(const AItems: array of IDataValue): IDataTupleValue;
|
|
begin
|
|
// Create a new value instance. The instance itself knows its item count
|
|
// and will report the singleton "Tuple" type via its DataType property.
|
|
Result := TImplDataTupleValue.Create(AItems);
|
|
end;
|
|
|
|
end.
|