Files
MycLib/Src/Data/Myc.Data.Types.Tuple.pas
T
Michael Schimmel 27f1cc5486 Data Types
2025-08-25 10:26:48 +02:00

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.