Vector type

This commit is contained in:
Michael Schimmel
2025-08-27 15:15:47 +02:00
parent 3daf55a355
commit 644b3fa8fd
4 changed files with 634 additions and 4 deletions
+157 -3
View File
@@ -6,7 +6,7 @@ uses
System.SysUtils;
type
TDataKind = (dkVoid, dkOrdinal, dkFloat, dkText, dkTimestamp, dkDecimal, dkRecord, dkTuple, dkArray, dkEnum, dkMethod);
TDataKind = (dkVoid, dkOrdinal, dkFloat, dkText, dkTimestamp, dkDecimal, dkRecord, dkTuple, dkArray, dkVector, dkEnum, dkMethod);
IDataType = interface
{$region 'private'}
@@ -189,6 +189,27 @@ type
property ElementType: IDataType read GetElementType;
end;
// Represents a fixed-size vector of data values.
IDataVectorValue = interface(IDataValue)
{$region 'private'}
function GetElementCount: Integer;
function GetItem(Idx: Integer): IDataValue;
{$endregion}
property ElementCount: Integer read GetElementCount;
property Items[Idx: Integer]: IDataValue read GetItem; default;
end;
// Represents the type of a fixed-size vector.
IDataVectorType = interface(IDataType)
{$region 'private'}
function GetElementType: IDataType;
function GetElementCount: Integer;
{$endregion}
function CreateValue(const AItems: array of IDataValue): IDataVectorValue;
property ElementType: IDataType read GetElementType;
property ElementCount: Integer read GetElementCount;
end;
TDataType = record
type
TValue = record
@@ -207,6 +228,7 @@ type
function AsRecord: IDataRecordValue; inline;
function AsTuple: IDataTupleValue; inline;
function AsArray: IDataArrayValue; inline;
function AsVector: IDataVectorValue; inline;
function AsEnum: IDataEnumValue; inline;
function AsMethod: IDataMethodValue; inline;
function AsVoid: IDataVoidValue; inline;
@@ -479,6 +501,36 @@ type
property ElementType: IDataType read GetElementType;
end;
TVector = record
type
TValue = record
private
FVectorValue: IDataVectorValue;
function GetDataType: TDataType.TVector;
function GetItems(Idx: Integer): TDataType.TValue; inline;
function GetElementCount: Integer; inline;
public
constructor Create(const AVectorValue: IDataVectorValue);
class operator Implicit(const A: IDataVectorValue): TDataType.TVector.TValue; overload; inline;
class operator Implicit(const A: TDataType.TVector.TValue): IDataVectorValue; overload; inline;
class operator Implicit(const A: TDataType.TVector.TValue): TDataType.TValue; overload; inline;
property ElementCount: Integer read GetElementCount;
property Items[Idx: Integer]: TDataType.TValue read GetItems; default;
property DataType: TDataType.TVector read GetDataType;
end;
private
FVectorType: IDataVectorType;
function GetElementType: IDataType; inline;
function GetElementCount: Integer; inline;
public
constructor Create(const AVectorType: IDataVectorType);
class operator Implicit(const A: IDataVectorType): TDataType.TVector; overload; inline;
class operator Implicit(const A: TDataType.TVector): IDataVectorType; overload; inline;
function CreateValue(const AItems: array of IDataValue): TDataType.TVector.TValue;
property ElementType: IDataType read GetElementType;
property ElementCount: Integer read GetElementCount;
end;
TMethod = record
type
TProc = reference to function(const AValue: TDataType.TValue): TDataType.TValue;
@@ -530,6 +582,7 @@ type
class operator Implicit(const A: TDataType.TRecord): TDataType; overload; inline;
class operator Implicit(const A: TDataType.TTuple): TDataType; overload; inline;
class operator Implicit(const A: TDataType.TArray): TDataType; overload; inline;
class operator Implicit(const A: TDataType.TVector): TDataType; overload; inline;
// Type factories
class function Void: TDataType.TVoid; static; inline;
@@ -541,8 +594,10 @@ type
class function Tuple: TDataType.TTuple; static; inline;
class function MethodOf(const AArgType, AResultType: IDataType): TDataType.TMethod; static;
class function ArrayOf(const AElementType: IDataType): TDataType.TArray; static;
class function VectorOf(const AElementType: IDataType; const AElementCount: Integer): TDataType.TVector; static;
class function RecordOf(const Fields: TArray<TDataRecordField>): TDataType.TRecord; overload; static;
class function RecordOf(const Fields: array of TDataRecordField): TDataType.TRecord; overload; static;
class function RecordOf<T>: TDataType.TRecord; overload; static;
class function EnumOf(const AName: string; const AIdentifiers: array of string): TDataType.TEnum; static;
function AsOrdinal: TDataType.TOrdinal; inline;
@@ -553,6 +608,7 @@ type
function AsRecord: TDataType.TRecord; inline;
function AsTuple: TDataType.TTuple; inline;
function AsArray: TDataType.TArray; inline;
function AsVector: TDataType.TVector; inline;
function AsEnum: TDataType.TEnum; inline;
function AsMethod: TDataType.TMethod; inline;
@@ -572,6 +628,7 @@ uses
Myc.Data.Types.Timestamp,
Myc.Data.Types.Decimal,
Myc.Data.Types.Arrays,
Myc.Data.Types.Vector,
Myc.Data.Types.Records,
Myc.Data.Types.Tuple,
Myc.Data.Types.Enum,
@@ -1264,6 +1321,75 @@ begin
Result := A.FArrayType;
end;
{ TDataType.TVector.TValue }
constructor TDataType.TVector.TValue.Create(const AVectorValue: IDataVectorValue);
begin
FVectorValue := AVectorValue;
end;
function TDataType.TVector.TValue.GetDataType: TDataType.TVector;
begin
Result := IDataVectorType(FVectorValue.DataType);
end;
function TDataType.TVector.TValue.GetElementCount: Integer;
begin
Result := FVectorValue.ElementCount;
end;
function TDataType.TVector.TValue.GetItems(Idx: Integer): TDataType.TValue;
begin
Result.Create(FVectorValue.Items[Idx]);
end;
class operator TDataType.TVector.TValue.Implicit(const A: IDataVectorValue): TDataType.TVector.TValue;
begin
Result.FVectorValue := A;
end;
class operator TDataType.TVector.TValue.Implicit(const A: TDataType.TVector.TValue): IDataVectorValue;
begin
Result := A.FVectorValue;
end;
class operator TDataType.TVector.TValue.Implicit(const A: TDataType.TVector.TValue): TDataType.TValue;
begin
Result.Create(A.FVectorValue);
end;
{ TDataType.TVector }
constructor TDataType.TVector.Create(const AVectorType: IDataVectorType);
begin
FVectorType := AVectorType;
end;
function TDataType.TVector.CreateValue(const AItems: array of IDataValue): TDataType.TVector.TValue;
begin
Result.Create(FVectorType.CreateValue(AItems));
end;
function TDataType.TVector.GetElementCount: Integer;
begin
Result := FVectorType.ElementCount;
end;
function TDataType.TVector.GetElementType: IDataType;
begin
Result := FVectorType.ElementType;
end;
class operator TDataType.TVector.Implicit(const A: IDataVectorType): TDataType.TVector;
begin
Result.FVectorType := A;
end;
class operator TDataType.TVector.Implicit(const A: TDataType.TVector): IDataVectorType;
begin
Result := A.FVectorType;
end;
{ TDataType }
constructor TDataType.Create(const ADataType: IDataType);
@@ -1330,16 +1456,19 @@ end;
class function TDataType.RecordOf(const Fields: TArray<TDataRecordField>): TDataType.TRecord;
begin
// The TImplDataRecordType now manages its own instances.
Result.Create(TImplDataRecordType.GetInstance(Fields));
end;
class function TDataType.RecordOf(const Fields: array of TDataRecordField): TDataType.TRecord;
begin
// The TImplDataRecordType now manages its own instances.
Result.Create(TImplDataRecordType.GetInstance(Fields));
end;
class function TDataType.RecordOf<T>: TDataType.TRecord;
begin
Result.Create(TImplDataRecordType.GetInstance<T>);
end;
class function TDataType.Text: TDataType.TText;
begin
Result.Create(TImplDataTextType.Singleton);
@@ -1355,6 +1484,12 @@ begin
Result.Create(TImplDataTupleType.Singleton);
end;
class function TDataType.VectorOf(const AElementType: IDataType; const AElementCount: Integer): TDataType.TVector;
begin
// The TImplDataVectorType now manages its own instances.
Result.Create(TImplDataVectorType.GetInstance(AElementType, AElementCount));
end;
class function TDataType.Void: TDataType.TVoid;
begin
Result.Create(TImplDataVoidType.Singleton);
@@ -1375,6 +1510,11 @@ begin
Result.FDataType := A.FArrayType;
end;
class operator TDataType.Implicit(const A: TDataType.TVector): TDataType;
begin
Result.FDataType := A.FVectorType;
end;
class operator TDataType.Implicit(const A: TDataType.TDecimal): TDataType;
begin
Result.FDataType := A.FDecimalType;
@@ -1503,6 +1643,13 @@ begin
Result := IDataTupleValue(FDataValue);
end;
function TDataType.TValue.AsVector: IDataVectorValue;
begin
if (FDataValue.DataType.Kind <> dkVector) then
raise EInvalidCast.Create('Vector expected');
Result := IDataVectorValue(FDataValue);
end;
function TDataType.TValue.AsVoid: IDataVoidValue;
begin
if (FDataValue.DataType.Kind <> dkVoid) then
@@ -1598,4 +1745,11 @@ begin
Result.Create(IDataTupleType(FDataType));
end;
function TDataType.AsVector: TDataType.TVector;
begin
if (FDataType.Kind <> dkVector) then
raise EInvalidCast.Create('Vector expected');
Result.Create(IDataVectorType(FDataType));
end;
end.