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; 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.