diff --git a/Src/Data/Myc.Data.Types.Enum.pas b/Src/Data/Myc.Data.Types.Enum.pas index 366cd4f..e0d8911 100644 --- a/Src/Data/Myc.Data.Types.Enum.pas +++ b/Src/Data/Myc.Data.Types.Enum.pas @@ -17,12 +17,11 @@ type function GetKind: TDataKind; function GetIdentifier(Idx: Integer): string; function GetIdentifierCount: Integer; - function IndexOf(const AIdentifier: string): Integer; - function CreateValue(const AValue: Integer): IDataEnumValue; overload; - function CreateValue(const AIdentifier: string): IDataEnumValue; overload; public constructor Create(const AName: string; const AIdentifiers: array of string); destructor Destroy; override; + function IndexOf(const AIdentifier: string): Integer; + function CreateValue(const AValue: Integer): IDataEnumValue; end; implementation @@ -101,16 +100,6 @@ begin Result := TImplDataEnumValue.Create(Self, AValue); end; -function TImplDataEnumType.CreateValue(const AIdentifier: string): IDataEnumValue; -var - idx: Integer; -begin - idx := IndexOf(AIdentifier); - if idx < 0 then - raise EArgumentException.CreateFmt('Unknown identifier: %s', [AIdentifier]); - Result := CreateValue(idx); -end; - { TImplDataEnumValue } constructor TImplDataEnumValue.Create(const ADataType: IDataEnumType; const AValue: Integer); diff --git a/Src/Data/Myc.Data.Types.pas b/Src/Data/Myc.Data.Types.pas index 67af8bb..c6bbda1 100644 --- a/Src/Data/Myc.Data.Types.pas +++ b/Src/Data/Myc.Data.Types.pas @@ -8,37 +8,40 @@ uses System.RTTI; type - TDataKind = (dkOrdinal, dkFloat, dkText, dkTimestamp, dkRecord, dkTuple, dkArray, dkEnum, dkMethod); + // Corrected dfVoid to dkVoid and added void type support + TDataKind = (dkVoid, dkOrdinal, dkFloat, dkText, dkTimestamp, dkRecord, dkTuple, dkArray, dkEnum, dkMethod); IDataType = interface + {$region 'private'} function GetName: String; function GetKind: TDataKind; + {$endregion} property Name: String read GetName; property Kind: TDataKind read GetKind; end; IDataValue = interface + {$region 'private'} function GetDataType: IDataType; function GetAsString: string; + {$endregion} function AsTValue: TValue; property DataType: IDataType read GetDataType; property AsString: string read GetAsString; end; - IDataOrdinalValue = interface(IDataValue) - function GetValue: Int64; - property Value: Int64 read GetValue; + IDataVoidValue = interface(IDataValue) end; - // Helper for IDataOrdinalValue - TDataOrdinalValue = record - private - FOrdinalValue: IDataOrdinalValue; - function GetValue: Int64; inline; - public - constructor Create(const AOrdinalValue: IDataOrdinalValue); - class operator Implicit(const A: IDataOrdinalValue): TDataOrdinalValue; overload; - class operator Implicit(const A: TDataOrdinalValue): IDataOrdinalValue; overload; + IDataVoidType = interface(IDataType) + function GetValue: IDataVoidValue; + property Value: IDataVoidValue read GetValue; + end; + + IDataOrdinalValue = interface(IDataValue) + {$region 'private'} + function GetValue: Int64; + {$endregion} property Value: Int64 read GetValue; end; @@ -47,19 +50,9 @@ type end; IDataFloatValue = interface(IDataValue) + {$region 'private'} function GetValue: Double; - property Value: Double read GetValue; - end; - - // Helper for IDataFloatValue - TDataFloatValue = record - private - FFloatValue: IDataFloatValue; - function GetValue: Double; inline; - public - constructor Create(const AFloatValue: IDataFloatValue); - class operator Implicit(const A: IDataFloatValue): TDataFloatValue; overload; - class operator Implicit(const A: TDataFloatValue): IDataFloatValue; overload; + {$endregion} property Value: Double read GetValue; end; @@ -68,19 +61,9 @@ type end; IDataTextValue = interface(IDataValue) + {$region 'private'} function GetValue: string; - property Value: string read GetValue; - end; - - // Helper for IDataTextValue - TDataTextValue = record - private - FTextValue: IDataTextValue; - function GetValue: string; inline; - public - constructor Create(const ATextValue: IDataTextValue); - class operator Implicit(const A: IDataTextValue): TDataTextValue; overload; - class operator Implicit(const A: TDataTextValue): IDataTextValue; overload; + {$endregion} property Value: string read GetValue; end; @@ -89,19 +72,9 @@ type end; IDataTimestampValue = interface(IDataValue) + {$region 'private'} function GetValue: TDateTime; - property Value: TDateTime read GetValue; - end; - - // Helper for IDataTimestampValue - TDataTimestampValue = record - private - FTimestampValue: IDataTimestampValue; - function GetValue: TDateTime; inline; - public - constructor Create(const ATimestampValue: IDataTimestampValue); - class operator Implicit(const A: IDataTimestampValue): TDataTimestampValue; overload; - class operator Implicit(const A: TDataTimestampValue): IDataTimestampValue; overload; + {$endregion} property Value: TDateTime read GetValue; end; @@ -110,28 +83,19 @@ type end; IDataEnumValue = interface(IDataValue) + {$region 'private'} function GetValue: Integer; - property Value: Integer read GetValue; - end; - - // Helper for IDataEnumValue - TDataEnumValue = record - private - FEnumValue: IDataEnumValue; - function GetValue: Integer; inline; - public - constructor Create(const AEnumValue: IDataEnumValue); - class operator Implicit(const A: IDataEnumValue): TDataEnumValue; overload; - class operator Implicit(const A: TDataEnumValue): IDataEnumValue; overload; + {$endregion} property Value: Integer read GetValue; end; IDataEnumType = interface(IDataType) + {$region 'private'} function GetIdentifier(Idx: Integer): string; function GetIdentifierCount: Integer; + {$endregion} function IndexOf(const AIdentifier: string): Integer; - function CreateValue(const AValue: Integer): IDataEnumValue; overload; - function CreateValue(const AIdentifier: string): IDataEnumValue; overload; + function CreateValue(const AValue: Integer): IDataEnumValue; property IdentifierCount: Integer read GetIdentifierCount; property Identifiers[Idx: Integer]: string read GetIdentifier; default; end; @@ -147,18 +111,6 @@ type property Value: TDataMethodProc read GetValue; end; - // Helper for IDataMethodValue - TDataMethodValue = record - private - FMethodValue: IDataMethodValue; - function GetValue: TDataMethodProc; inline; - public - constructor Create(const AMethodValue: IDataMethodValue); - class operator Implicit(const A: IDataMethodValue): TDataMethodValue; overload; - class operator Implicit(const A: TDataMethodValue): IDataMethodValue; overload; - property Value: TDataMethodProc read GetValue; - end; - // Represents the type of a method data value, including its signature. IDataMethodType = interface(IDataType) {$region 'private'} @@ -171,31 +123,23 @@ type end; IDataRecordValue = interface(IDataValue) + {$region 'private'} function GetItem(Idx: Integer): IDataValue; - property Items[Idx: Integer]: IDataValue read GetItem; default; - end; - - // Helper for IDataRecordValue - TDataRecordValue = record - private - FRecordValue: IDataRecordValue; - function GetItem(Idx: Integer): IDataValue; inline; - public - constructor Create(const ARecordValue: IDataRecordValue); - class operator Implicit(const A: IDataRecordValue): TDataRecordValue; overload; - class operator Implicit(const A: TDataRecordValue): IDataRecordValue; overload; + {$endregion} property Items[Idx: Integer]: IDataValue read GetItem; default; end; TRecordField = record - Name: string; DataType: IDataType; + Name: string; constructor Create(const AName: string; const ADataType: IDataType); end; IDataRecordType = interface(IDataType) + {$region 'private'} function GetFieldCount: Integer; function GetField(Idx: Integer): TRecordField; + {$endregion} function IndexOf(const AName: string): Integer; function CreateValue(const AItems: array of IDataValue): IDataRecordValue; property FieldCount: Integer read GetFieldCount; @@ -203,22 +147,10 @@ type end; IDataTupleValue = interface(IDataValue) + {$region 'private'} function GetItemCount: Integer; function GetItem(Idx: Integer): IDataValue; - property ItemCount: Integer read GetItemCount; - property Items[Idx: Integer]: IDataValue read GetItem; default; - end; - - // Helper for IDataTupleValue - TDataTupleValue = record - private - FTupleValue: IDataTupleValue; - function GetItemCount: Integer; inline; - function GetItem(Idx: Integer): IDataValue; inline; - public - constructor Create(const ATupleValue: IDataTupleValue); - class operator Implicit(const A: IDataTupleValue): TDataTupleValue; overload; - class operator Implicit(const A: TDataTupleValue): IDataTupleValue; overload; + {$endregion} property ItemCount: Integer read GetItemCount; property Items[Idx: Integer]: IDataValue read GetItem; default; end; @@ -228,28 +160,18 @@ type end; IDataArrayValue = interface(IDataValue) + {$region 'private'} function GetElementCount: Integer; function GetItem(Idx: Integer): IDataValue; - property ElementCount: Integer read GetElementCount; - property Items[Idx: Integer]: IDataValue read GetItem; default; - end; - - // Helper for IDataArrayValue - TDataArrayValue = record - private - FArrayValue: IDataArrayValue; - function GetElementCount: Integer; inline; - function GetItem(Idx: Integer): IDataValue; inline; - public - constructor Create(const AArrayValue: IDataArrayValue); - class operator Implicit(const A: IDataArrayValue): TDataArrayValue; overload; - class operator Implicit(const A: TDataArrayValue): IDataArrayValue; overload; + {$endregion} property ElementCount: Integer read GetElementCount; property Items[Idx: Integer]: IDataValue read GetItem; default; end; IDataArrayType = interface(IDataType) + {$region 'private'} function GetElementType: IDataType; + {$endregion} function CreateValue(const AItems: array of IDataValue): IDataArrayValue; property ElementType: IDataType read GetElementType; end; @@ -264,40 +186,54 @@ type constructor Create(const ADataValue: IDataValue); // Casting - function AsOrdinal: TDataOrdinalValue; - function AsFloat: TDataFloatValue; - function AsText: TDataTextValue; - function AsTimestamp: TDataTimestampValue; - function AsRecord: TDataRecordValue; - function AsTuple: TDataTupleValue; - function AsArray: TDataArrayValue; - function AsEnum: TDataEnumValue; - function AsMethod: TDataMethodValue; + function AsOrdinal: IDataOrdinalValue; inline; + function AsFloat: IDataFloatValue; inline; + function AsText: IDataTextValue; inline; + function AsTimestamp: IDataTimestampValue; inline; + function AsRecord: IDataRecordValue; inline; + function AsTuple: IDataTupleValue; inline; + function AsArray: IDataArrayValue; inline; + function AsEnum: IDataEnumValue; inline; + function AsMethod: IDataMethodValue; inline; + function AsVoid: IDataVoidValue; inline; - class operator Implicit(const A: IDataValue): TDataType.TValue; overload; - class operator Implicit(const A: TDataType.TValue): IDataValue; overload; - class operator Implicit(const A: TDataOrdinalValue): TDataType.TValue; overload; - class operator Implicit(const A: TDataFloatValue): TDataType.TValue; overload; - class operator Implicit(const A: TDataTextValue): TDataType.TValue; overload; - class operator Implicit(const A: TDataTimestampValue): TDataType.TValue; overload; - class operator Implicit(const A: TDataEnumValue): TDataType.TValue; overload; - class operator Implicit(const A: TDataMethodValue): TDataType.TValue; overload; - class operator Implicit(const A: TDataRecordValue): TDataType.TValue; overload; - class operator Implicit(const A: TDataTupleValue): TDataType.TValue; overload; - class operator Implicit(const A: TDataArrayValue): TDataType.TValue; overload; + class operator Implicit(const A: IDataValue): TDataType.TValue; overload; inline; + class operator Implicit(const A: TDataType.TValue): IDataValue; overload; inline; + + class operator Implicit(const A: IDataOrdinalValue): TDataType.TValue; overload; inline; + class operator Implicit(const A: IDataFloatValue): TDataType.TValue; overload; inline; + class operator Implicit(const A: IDataTextValue): TDataType.TValue; overload; inline; + class operator Implicit(const A: IDataTimestampValue): TDataType.TValue; overload; inline; + class operator Implicit(const A: IDataEnumValue): TDataType.TValue; overload; inline; + class operator Implicit(const A: IDataMethodValue): TDataType.TValue; overload; inline; + class operator Implicit(const A: IDataRecordValue): TDataType.TValue; overload; inline; + class operator Implicit(const A: IDataTupleValue): TDataType.TValue; overload; inline; + class operator Implicit(const A: IDataArrayValue): TDataType.TValue; overload; inline; + class operator Implicit(const A: IDataVoidValue): TDataType.TValue; overload; inline; property DataValue: IDataValue read FDataValue; property DataType: IDataType read GetDataType; end; + TVoid = record + private + FVoidType: IDataVoidType; + function GetValue: IDataVoidValue; inline; + public + constructor Create(const AVoidType: IDataVoidType); + class operator Implicit(const A: IDataVoidType): TDataType.TVoid; overload; inline; + class operator Implicit(const A: TDataType.TVoid): IDataVoidType; overload; inline; + property Value: IDataVoidValue read GetValue; + end; + TOrdinal = record private FOrdinalType: IDataOrdinalType; public constructor Create(const AOrdinalType: IDataOrdinalType); - class operator Implicit(const A: IDataOrdinalType): TDataType.TOrdinal; overload; - class operator Implicit(const A: TDataType.TOrdinal): IDataOrdinalType; overload; - function CreateValue(Init: Int64): TDataOrdinalValue; inline; + class operator Implicit(const A: IDataOrdinalType): TDataType.TOrdinal; overload; inline; + class operator Implicit(const A: TDataType.TOrdinal): IDataOrdinalType; overload; inline; + function CreateValue(Init: Int64): IDataOrdinalValue; inline; end; TFloat = record @@ -305,9 +241,9 @@ type FFloatType: IDataFloatType; public constructor Create(const AFloatType: IDataFloatType); - class operator Implicit(const A: IDataFloatType): TDataType.TFloat; overload; - class operator Implicit(const A: TDataType.TFloat): IDataFloatType; overload; - function CreateValue(Init: Double): TDataFloatValue; inline; + class operator Implicit(const A: IDataFloatType): TDataType.TFloat; overload; inline; + class operator Implicit(const A: TDataType.TFloat): IDataFloatType; overload; inline; + function CreateValue(Init: Double): IDataFloatValue; inline; end; TText = record @@ -315,9 +251,9 @@ type FTextType: IDataTextType; public constructor Create(const ATextType: IDataTextType); - class operator Implicit(const A: IDataTextType): TDataType.TText; overload; - class operator Implicit(const A: TDataType.TText): IDataTextType; overload; - function CreateValue(const AValue: string): TDataTextValue; inline; + class operator Implicit(const A: IDataTextType): TDataType.TText; overload; inline; + class operator Implicit(const A: TDataType.TText): IDataTextType; overload; inline; + function CreateValue(const AValue: string): IDataTextValue; inline; end; TTimestamp = record @@ -325,9 +261,9 @@ type FTimestampType: IDataTimestampType; public constructor Create(const ATimestampType: IDataTimestampType); - class operator Implicit(const A: IDataTimestampType): TDataType.TTimestamp; overload; - class operator Implicit(const A: TDataType.TTimestamp): IDataTimestampType; overload; - function CreateValue(const AValue: TDateTime): TDataTimestampValue; inline; + class operator Implicit(const A: IDataTimestampType): TDataType.TTimestamp; overload; inline; + class operator Implicit(const A: TDataType.TTimestamp): IDataTimestampType; overload; inline; + function CreateValue(const AValue: TDateTime): IDataTimestampValue; inline; end; TEnum = record @@ -337,11 +273,11 @@ type function GetIdentifierCount: Integer; inline; public constructor Create(const AEnumType: IDataEnumType); - class operator Implicit(const A: IDataEnumType): TDataType.TEnum; overload; - class operator Implicit(const A: TDataType.TEnum): IDataEnumType; overload; + class operator Implicit(const A: IDataEnumType): TDataType.TEnum; overload; inline; + class operator Implicit(const A: TDataType.TEnum): IDataEnumType; overload; inline; function IndexOf(const AIdentifier: string): Integer; inline; - function CreateValue(const AValue: Integer): TDataEnumValue; overload; inline; - function CreateValue(const AIdentifier: string): TDataEnumValue; overload; inline; + function CreateValue(const AValue: Integer): IDataEnumValue; overload; inline; + function CreateValue(const AIdentifier: string): IDataEnumValue; overload; inline; property IdentifierCount: Integer read GetIdentifierCount; property Identifiers[Idx: Integer]: string read GetIdentifier; default; end; @@ -353,10 +289,10 @@ type function GetField(Idx: Integer): TRecordField; inline; public constructor Create(const ARecordType: IDataRecordType); - class operator Implicit(const A: IDataRecordType): TDataType.TRecord; overload; - class operator Implicit(const A: TDataType.TRecord): IDataRecordType; overload; + class operator Implicit(const A: IDataRecordType): TDataType.TRecord; overload; inline; + class operator Implicit(const A: TDataType.TRecord): IDataRecordType; overload; inline; function IndexOf(const AName: string): Integer; inline; - function CreateValue(const AItems: array of IDataValue): TDataRecordValue; + function CreateValue(const AItems: array of IDataValue): IDataRecordValue; property FieldCount: Integer read GetFieldCount; property Fields[Idx: Integer]: TRecordField read GetField; default; end; @@ -366,9 +302,9 @@ type FTupleType: IDataTupleType; public constructor Create(const ATupleType: IDataTupleType); - class operator Implicit(const A: IDataTupleType): TDataType.TTuple; overload; - class operator Implicit(const A: TDataType.TTuple): IDataTupleType; overload; - function CreateValue(const AItems: array of IDataValue): TDataTupleValue; + class operator Implicit(const A: IDataTupleType): TDataType.TTuple; overload; inline; + class operator Implicit(const A: TDataType.TTuple): IDataTupleType; overload; inline; + function CreateValue(const AItems: array of IDataValue): IDataTupleValue; end; TArray = record @@ -377,9 +313,9 @@ type function GetElementType: IDataType; inline; public constructor Create(const AArrayType: IDataArrayType); - class operator Implicit(const A: IDataArrayType): TDataType.TArray; overload; - class operator Implicit(const A: TDataType.TArray): IDataArrayType; overload; - function CreateValue(const AItems: array of IDataValue): TDataArrayValue; + class operator Implicit(const A: IDataArrayType): TDataType.TArray; overload; inline; + class operator Implicit(const A: TDataType.TArray): IDataArrayType; overload; inline; + function CreateValue(const AItems: array of IDataValue): IDataArrayValue; property ElementType: IDataType read GetElementType; end; @@ -392,11 +328,11 @@ type function GetResultType: IDataType; inline; public constructor Create(const AMethodType: IDataMethodType); - class operator Implicit(const A: IDataMethodType): TDataType.TMethod; overload; - class operator Implicit(const A: TDataType.TMethod): IDataMethodType; overload; + class operator Implicit(const A: IDataMethodType): TDataType.TMethod; overload; inline; + class operator Implicit(const A: TDataType.TMethod): IDataMethodType; overload; inline; property ArgType: IDataType read GetArgType; property ResultType: IDataType read GetResultType; - function CreateValue(const Proc: TProc): TDataMethodValue; inline; + function CreateValue(const Proc: TProc): IDataMethodValue; inline; end; strict private @@ -412,48 +348,50 @@ type public constructor Create(const ADataType: IDataType); - class operator Implicit(const A: IDataType): TDataType; overload; - class operator Implicit(const A: TDataType): IDataType; overload; - class operator Implicit(const A: TDataType.TOrdinal): TDataType; overload; - class operator Implicit(const A: TDataType.TFloat): TDataType; overload; - class operator Implicit(const A: TDataType.TText): TDataType; overload; - class operator Implicit(const A: TDataType.TTimestamp): TDataType; overload; - class operator Implicit(const A: TDataType.TEnum): TDataType; overload; - class operator Implicit(const A: TDataType.TMethod): TDataType; overload; - class operator Implicit(const A: TDataType.TRecord): TDataType; overload; - class operator Implicit(const A: TDataType.TTuple): TDataType; overload; - class operator Implicit(const A: TDataType.TArray): TDataType; overload; + class operator Implicit(const A: IDataType): TDataType; overload; inline; + class operator Implicit(const A: TDataType): IDataType; overload; inline; + class operator Implicit(const A: TDataType.TVoid): TDataType; overload; inline; + class operator Implicit(const A: TDataType.TOrdinal): TDataType; overload; inline; + class operator Implicit(const A: TDataType.TFloat): TDataType; overload; inline; + class operator Implicit(const A: TDataType.TText): TDataType; overload; inline; + class operator Implicit(const A: TDataType.TTimestamp): TDataType; overload; inline; + class operator Implicit(const A: TDataType.TEnum): TDataType; overload; inline; + class operator Implicit(const A: TDataType.TMethod): TDataType; overload; inline; + 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; // Type factories - class function Ordinal: TDataType.TOrdinal; static; - class function Float: TDataType.TFloat; static; - class function Text: TDataType.TText; static; - class function Timestamp: TDataType.TTimestamp; static; - class function Tuple: TDataType.TTuple; static; + class function Void: TDataType.TVoid; static; inline; + class function Ordinal: TDataType.TOrdinal; static; inline; + class function Float: TDataType.TFloat; static; inline; + class function Text: TDataType.TText; static; inline; + class function Timestamp: TDataType.TTimestamp; static; inline; + 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 RecordOf(const Fields: TArray): TDataType.TRecord; overload; static; class function RecordOf(const Fields: array of TRecordField): TDataType.TRecord; overload; static; class function EnumOf(const AName: string; const AIdentifiers: array of string): TDataType.TEnum; static; - // Value factories moved from TValue - class function FromOrdinal(const AValue: Int64): TDataOrdinalValue; static; - class function FromFloat(const AValue: Double): TDataFloatValue; static; - class function FromText(const AValue: string): TDataTextValue; static; - class function FromTimestamp(const AValue: TDateTime): TDataTimestampValue; static; - class function FromTuple(const AItems: array of IDataValue): TDataTupleValue; static; - class function FromMethod(const AMethodType: TDataType.TMethod; const AValue: TMethod.TProc): TDataMethodValue; static; + // Value factories + class function FromOrdinal(const AValue: Int64): IDataOrdinalValue; static; inline; + class function FromFloat(const AValue: Double): IDataFloatValue; static; inline; + class function FromText(const AValue: string): IDataTextValue; static; inline; + class function FromTimestamp(const AValue: TDateTime): IDataTimestampValue; static; inline; + class function FromTuple(const AItems: array of IDataValue): IDataTupleValue; static; + class function FromMethod(const AMethodType: TDataType.TMethod; const AValue: TMethod.TProc): IDataMethodValue; static; inline; // Casting - function AsOrdinal: TDataType.TOrdinal; - function AsFloat: TDataType.TFloat; - function AsText: TDataType.TText; - function AsTimestamp: TDataType.TTimestamp; - function AsRecord: TDataType.TRecord; - function AsTuple: TDataType.TTuple; - function AsArray: TDataType.TArray; - function AsEnum: TDataType.TEnum; - function AsMethod: TDataType.TMethod; + function AsOrdinal: TDataType.TOrdinal; inline; + function AsFloat: TDataType.TFloat; inline; + function AsText: TDataType.TText; inline; + function AsTimestamp: TDataType.TTimestamp; inline; + function AsRecord: TDataType.TRecord; inline; + function AsTuple: TDataType.TTuple; inline; + function AsArray: TDataType.TArray; inline; + function AsEnum: TDataType.TEnum; inline; + function AsMethod: TDataType.TMethod; inline; property DataType: IDataType read FDataType; property Name: String read GetName; @@ -465,6 +403,7 @@ implementation uses System.SyncObjs, System.Generics.Defaults, + Myc.Data.Types.Void, Myc.Data.Types.Ordinal, Myc.Data.Types.Float, Myc.Data.Types.Text, @@ -483,26 +422,26 @@ begin DataType := ADataType; end; -{ TDataOrdinalValue } +{ TDataType.TVoid } -constructor TDataOrdinalValue.Create(const AOrdinalValue: IDataOrdinalValue); +constructor TDataType.TVoid.Create(const AVoidType: IDataVoidType); begin - FOrdinalValue := AOrdinalValue; + FVoidType := AVoidType; end; -function TDataOrdinalValue.GetValue: Int64; +function TDataType.TVoid.GetValue: IDataVoidValue; begin - Result := FOrdinalValue.Value; + Result := FVoidType.Value; end; -class operator TDataOrdinalValue.Implicit(const A: TDataOrdinalValue): IDataOrdinalValue; +class operator TDataType.TVoid.Implicit(const A: IDataVoidType): TDataType.TVoid; begin - Result := A.FOrdinalValue; + Result.FVoidType := A; end; -class operator TDataOrdinalValue.Implicit(const A: IDataOrdinalValue): TDataOrdinalValue; +class operator TDataType.TVoid.Implicit(const A: TDataType.TVoid): IDataVoidType; begin - Result.FOrdinalValue := A; + Result := A.FVoidType; end; { TDataType.TOrdinal } @@ -512,7 +451,7 @@ begin FOrdinalType := AOrdinalType; end; -function TDataType.TOrdinal.CreateValue(Init: Int64): TDataOrdinalValue; +function TDataType.TOrdinal.CreateValue(Init: Int64): IDataOrdinalValue; begin Result := FOrdinalType.CreateValue(Init); end; @@ -527,28 +466,6 @@ begin Result.FOrdinalType := A; end; -{ TDataFloatValue } - -constructor TDataFloatValue.Create(const AFloatValue: IDataFloatValue); -begin - FFloatValue := AFloatValue; -end; - -function TDataFloatValue.GetValue: Double; -begin - Result := FFloatValue.Value; -end; - -class operator TDataFloatValue.Implicit(const A: IDataFloatValue): TDataFloatValue; -begin - Result.FFloatValue := A; -end; - -class operator TDataFloatValue.Implicit(const A: TDataFloatValue): IDataFloatValue; -begin - Result := A.FFloatValue; -end; - { TDataType.TFloat } constructor TDataType.TFloat.Create(const AFloatType: IDataFloatType); @@ -556,7 +473,7 @@ begin FFloatType := AFloatType; end; -function TDataType.TFloat.CreateValue(Init: Double): TDataFloatValue; +function TDataType.TFloat.CreateValue(Init: Double): IDataFloatValue; begin Result := FFloatType.CreateValue(Init); end; @@ -571,28 +488,6 @@ begin Result := A.FFloatType; end; -{ TDataTextValue } - -constructor TDataTextValue.Create(const ATextValue: IDataTextValue); -begin - FTextValue := ATextValue; -end; - -function TDataTextValue.GetValue: string; -begin - Result := FTextValue.Value; -end; - -class operator TDataTextValue.Implicit(const A: IDataTextValue): TDataTextValue; -begin - Result.FTextValue := A; -end; - -class operator TDataTextValue.Implicit(const A: TDataTextValue): IDataTextValue; -begin - Result := A.FTextValue; -end; - { TDataType.TText } constructor TDataType.TText.Create(const ATextType: IDataTextType); @@ -600,7 +495,7 @@ begin FTextType := ATextType; end; -function TDataType.TText.CreateValue(const AValue: string): TDataTextValue; +function TDataType.TText.CreateValue(const AValue: string): IDataTextValue; begin Result := FTextType.CreateValue(AValue); end; @@ -615,28 +510,6 @@ begin Result := A.FTextType; end; -{ TDataTimestampValue } - -constructor TDataTimestampValue.Create(const ATimestampValue: IDataTimestampValue); -begin - FTimestampValue := ATimestampValue; -end; - -function TDataTimestampValue.GetValue: TDateTime; -begin - Result := FTimestampValue.Value; -end; - -class operator TDataTimestampValue.Implicit(const A: IDataTimestampValue): TDataTimestampValue; -begin - Result.FTimestampValue := A; -end; - -class operator TDataTimestampValue.Implicit(const A: TDataTimestampValue): IDataTimestampValue; -begin - Result := A.FTimestampValue; -end; - { TDataType.TTimestamp } constructor TDataType.TTimestamp.Create(const ATimestampType: IDataTimestampType); @@ -644,7 +517,7 @@ begin FTimestampType := ATimestampType; end; -function TDataType.TTimestamp.CreateValue(const AValue: TDateTime): TDataTimestampValue; +function TDataType.TTimestamp.CreateValue(const AValue: TDateTime): IDataTimestampValue; begin Result := FTimestampType.CreateValue(AValue); end; @@ -659,28 +532,6 @@ begin Result := A.FTimestampType; end; -{ TDataEnumValue } - -constructor TDataEnumValue.Create(const AEnumValue: IDataEnumValue); -begin - FEnumValue := AEnumValue; -end; - -function TDataEnumValue.GetValue: Integer; -begin - Result := FEnumValue.Value; -end; - -class operator TDataEnumValue.Implicit(const A: IDataEnumValue): TDataEnumValue; -begin - Result.FEnumValue := A; -end; - -class operator TDataEnumValue.Implicit(const A: TDataEnumValue): IDataEnumValue; -begin - Result := A.FEnumValue; -end; - { TDataType.TEnum } constructor TDataType.TEnum.Create(const AEnumType: IDataEnumType); @@ -688,14 +539,19 @@ begin FEnumType := AEnumType; end; -function TDataType.TEnum.CreateValue(const AValue: Integer): TDataEnumValue; +function TDataType.TEnum.CreateValue(const AValue: Integer): IDataEnumValue; begin Result := FEnumType.CreateValue(AValue); end; -function TDataType.TEnum.CreateValue(const AIdentifier: string): TDataEnumValue; +function TDataType.TEnum.CreateValue(const AIdentifier: string): IDataEnumValue; +var + idx: Integer; begin - Result := FEnumType.CreateValue(AIdentifier); + idx := IndexOf(AIdentifier); + if idx < 0 then + raise EArgumentException.CreateFmt('Unknown identifier: %s', [AIdentifier]); + Result := CreateValue(idx); end; function TDataType.TEnum.GetIdentifier(Idx: Integer): string; @@ -723,28 +579,6 @@ begin Result := A.FEnumType; end; -{ TDataMethodValue } - -constructor TDataMethodValue.Create(const AMethodValue: IDataMethodValue); -begin - FMethodValue := AMethodValue; -end; - -function TDataMethodValue.GetValue: TDataMethodProc; -begin - Result := FMethodValue.Value; -end; - -class operator TDataMethodValue.Implicit(const A: IDataMethodValue): TDataMethodValue; -begin - Result.FMethodValue := A; -end; - -class operator TDataMethodValue.Implicit(const A: TDataMethodValue): IDataMethodValue; -begin - Result := A.FMethodValue; -end; - { TDataType.TMethod } constructor TDataType.TMethod.Create(const AMethodType: IDataMethodType); @@ -752,7 +586,7 @@ begin FMethodType := AMethodType; end; -function TDataType.TMethod.CreateValue(const Proc: TProc): TDataMethodValue; +function TDataType.TMethod.CreateValue(const Proc: TProc): IDataMethodValue; begin if not Assigned(Proc) then raise EArgumentException.Create('Proc'); @@ -781,28 +615,6 @@ begin Result := A.FMethodType; end; -{ TDataRecordValue } - -constructor TDataRecordValue.Create(const ARecordValue: IDataRecordValue); -begin - FRecordValue := ARecordValue; -end; - -function TDataRecordValue.GetItem(Idx: Integer): IDataValue; -begin - Result := FRecordValue.GetItem(Idx); -end; - -class operator TDataRecordValue.Implicit(const A: IDataRecordValue): TDataRecordValue; -begin - Result.FRecordValue := A; -end; - -class operator TDataRecordValue.Implicit(const A: TDataRecordValue): IDataRecordValue; -begin - Result := A.FRecordValue; -end; - { TDataType.TRecord } constructor TDataType.TRecord.Create(const ARecordType: IDataRecordType); @@ -810,7 +622,7 @@ begin FRecordType := ARecordType; end; -function TDataType.TRecord.CreateValue(const AItems: array of IDataValue): TDataRecordValue; +function TDataType.TRecord.CreateValue(const AItems: array of IDataValue): IDataRecordValue; begin Result := FRecordType.CreateValue(AItems); end; @@ -840,33 +652,6 @@ begin Result := A.FRecordType; end; -{ TDataTupleValue } - -constructor TDataTupleValue.Create(const ATupleValue: IDataTupleValue); -begin - FTupleValue := ATupleValue; -end; - -function TDataTupleValue.GetItem(Idx: Integer): IDataValue; -begin - Result := FTupleValue.GetItem(Idx); -end; - -function TDataTupleValue.GetItemCount: Integer; -begin - Result := FTupleValue.ItemCount; -end; - -class operator TDataTupleValue.Implicit(const A: IDataTupleValue): TDataTupleValue; -begin - Result.FTupleValue := A; -end; - -class operator TDataTupleValue.Implicit(const A: TDataTupleValue): IDataTupleValue; -begin - Result := A.FTupleValue; -end; - { TDataType.TTuple } constructor TDataType.TTuple.Create(const ATupleType: IDataTupleType); @@ -874,7 +659,7 @@ begin FTupleType := ATupleType; end; -function TDataType.TTuple.CreateValue(const AItems: array of IDataValue): TDataTupleValue; +function TDataType.TTuple.CreateValue(const AItems: array of IDataValue): IDataTupleValue; begin Result := FTupleType.CreateValue(AItems); end; @@ -889,33 +674,6 @@ begin Result := A.FTupleType; end; -{ TDataArrayValue } - -constructor TDataArrayValue.Create(const AArrayValue: IDataArrayValue); -begin - FArrayValue := AArrayValue; -end; - -function TDataArrayValue.GetElementCount: Integer; -begin - Result := FArrayValue.ElementCount; -end; - -function TDataArrayValue.GetItem(Idx: Integer): IDataValue; -begin - Result := FArrayValue.GetItem(Idx); -end; - -class operator TDataArrayValue.Implicit(const A: IDataArrayValue): TDataArrayValue; -begin - Result.FArrayValue := A; -end; - -class operator TDataArrayValue.Implicit(const A: TDataArrayValue): IDataArrayValue; -begin - Result := A.FArrayValue; -end; - { TDataType.TArray } constructor TDataType.TArray.Create(const AArrayType: IDataArrayType); @@ -923,7 +681,7 @@ begin FArrayType := AArrayType; end; -function TDataType.TArray.CreateValue(const AItems: array of IDataValue): TDataArrayValue; +function TDataType.TArray.CreateValue(const AItems: array of IDataValue): IDataArrayValue; begin Result := FArrayType.CreateValue(AItems); end; @@ -1075,34 +833,34 @@ begin Result.Create(TImplDataFloatType.Singleton); end; -class function TDataType.FromFloat(const AValue: Double): TDataFloatValue; +class function TDataType.FromFloat(const AValue: Double): IDataFloatValue; begin Result := TDataType.Float.CreateValue(AValue); end; -class function TDataType.FromMethod(const AMethodType: TDataType.TMethod; const AValue: TMethod.TProc): TDataMethodValue; +class function TDataType.FromMethod(const AMethodType: TDataType.TMethod; const AValue: TMethod.TProc): IDataMethodValue; begin if not Assigned(AMethodType.FMethodType) then // Check underlying interface raise EArgumentException.Create('AMethodType'); Result := AMethodType.CreateValue(AValue); end; -class function TDataType.FromOrdinal(const AValue: Int64): TDataOrdinalValue; +class function TDataType.FromOrdinal(const AValue: Int64): IDataOrdinalValue; begin Result := TDataType.Ordinal.CreateValue(AValue); end; -class function TDataType.FromText(const AValue: string): TDataTextValue; +class function TDataType.FromText(const AValue: string): IDataTextValue; begin Result := TDataType.Text.CreateValue(AValue); end; -class function TDataType.FromTimestamp(const AValue: TDateTime): TDataTimestampValue; +class function TDataType.FromTimestamp(const AValue: TDateTime): IDataTimestampValue; begin Result := TDataType.Timestamp.CreateValue(AValue); end; -class function TDataType.FromTuple(const AItems: array of IDataValue): TDataTupleValue; +class function TDataType.FromTuple(const AItems: array of IDataValue): IDataTupleValue; begin Result := TDataType.Tuple.CreateValue(AItems); end; @@ -1187,6 +945,11 @@ begin Result.Create(TImplDataTupleType.Singleton); end; +class function TDataType.Void: TDataType.TVoid; +begin + Result.Create(TImplDataVoidType.Singleton); +end; + class operator TDataType.Implicit(const A: TDataType): IDataType; begin Result := A.FDataType; @@ -1197,9 +960,14 @@ begin Result.FDataType := A; end; -class operator TDataType.Implicit(const A: TDataType.TOrdinal): TDataType; +class operator TDataType.Implicit(const A: TDataType.TArray): TDataType; begin - Result.FDataType := A.FOrdinalType; + Result.FDataType := A.FArrayType; +end; + +class operator TDataType.Implicit(const A: TDataType.TEnum): TDataType; +begin + Result.FDataType := A.FEnumType; end; class operator TDataType.Implicit(const A: TDataType.TFloat): TDataType; @@ -1207,6 +975,21 @@ begin Result.FDataType := A.FFloatType; end; +class operator TDataType.Implicit(const A: TDataType.TMethod): TDataType; +begin + Result.FDataType := A.FMethodType; +end; + +class operator TDataType.Implicit(const A: TDataType.TOrdinal): TDataType; +begin + Result.FDataType := A.FOrdinalType; +end; + +class operator TDataType.Implicit(const A: TDataType.TRecord): TDataType; +begin + Result.FDataType := A.FRecordType; +end; + class operator TDataType.Implicit(const A: TDataType.TText): TDataType; begin Result.FDataType := A.FTextType; @@ -1217,29 +1000,14 @@ begin Result.FDataType := A.FTimestampType; end; -class operator TDataType.Implicit(const A: TDataType.TEnum): TDataType; -begin - Result.FDataType := A.FEnumType; -end; - -class operator TDataType.Implicit(const A: TDataType.TMethod): TDataType; -begin - Result.FDataType := A.FMethodType; -end; - -class operator TDataType.Implicit(const A: TDataType.TRecord): TDataType; -begin - Result.FDataType := A.FRecordType; -end; - class operator TDataType.Implicit(const A: TDataType.TTuple): TDataType; begin Result.FDataType := A.FTupleType; end; -class operator TDataType.Implicit(const A: TDataType.TArray): TDataType; +class operator TDataType.Implicit(const A: TDataType.TVoid): TDataType; begin - Result.FDataType := A.FArrayType; + Result.FDataType := A.FVoidType; end; { TDataType.TValue } @@ -1250,67 +1018,74 @@ begin FDataValue := ADataValue; end; -function TDataType.TValue.AsArray: TDataArrayValue; +function TDataType.TValue.AsArray: IDataArrayValue; begin if (FDataValue.DataType.Kind <> dkArray) then raise EInvalidCast.Create('Array expected'); - Result.Create(IDataArrayValue(FDataValue)); + Result := IDataArrayValue(FDataValue); end; -function TDataType.TValue.AsFloat: TDataFloatValue; -begin - if (FDataValue.DataType.Kind <> dkFloat) then - raise EInvalidCast.Create('Float expected'); - Result.Create(IDataFloatValue(FDataValue)); -end; - -function TDataType.TValue.AsMethod: TDataMethodValue; -begin - if (FDataValue.DataType.Kind <> dkMethod) then - raise EInvalidCast.Create('Method expected'); - Result.Create(IDataMethodValue(FDataValue)); -end; - -function TDataType.TValue.AsText: TDataTextValue; -begin - if (FDataValue.DataType.Kind <> dkText) then - raise EInvalidCast.Create('Text expected'); - Result.Create(IDataTextValue(FDataValue)); -end; - -function TDataType.TValue.AsTimestamp: TDataTimestampValue; -begin - if (FDataValue.DataType.Kind <> dkTimestamp) then - raise EInvalidCast.Create('Timestamp expected'); - Result.Create(IDataTimestampValue(FDataValue)); -end; - -function TDataType.TValue.AsOrdinal: TDataOrdinalValue; -begin - if (FDataValue.DataType.Kind <> dkOrdinal) then - raise EInvalidCast.Create('Ordinal expected'); - Result.Create(IDataOrdinalValue(FDataValue)); -end; - -function TDataType.TValue.AsRecord: TDataRecordValue; -begin - if (FDataValue.DataType.Kind <> dkRecord) then - raise EInvalidCast.Create('Record expected'); - Result.Create(IDataRecordValue(FDataValue)); -end; - -function TDataType.TValue.AsTuple: TDataTupleValue; -begin - if (FDataValue.DataType.Kind <> dkTuple) then - raise EInvalidCast.Create('Tuple expected'); - Result.Create(IDataTupleValue(FDataValue)); -end; - -function TDataType.TValue.AsEnum: TDataEnumValue; +function TDataType.TValue.AsEnum: IDataEnumValue; begin if (FDataValue.DataType.Kind <> dkEnum) then raise EInvalidCast.Create('Enum expected'); - Result.Create(IDataEnumValue(FDataValue)); + Result := IDataEnumValue(FDataValue); +end; + +function TDataType.TValue.AsFloat: IDataFloatValue; +begin + if (FDataValue.DataType.Kind <> dkFloat) then + raise EInvalidCast.Create('Float expected'); + Result := IDataFloatValue(FDataValue); +end; + +function TDataType.TValue.AsMethod: IDataMethodValue; +begin + if (FDataValue.DataType.Kind <> dkMethod) then + raise EInvalidCast.Create('Method expected'); + Result := IDataMethodValue(FDataValue); +end; + +function TDataType.TValue.AsOrdinal: IDataOrdinalValue; +begin + if (FDataValue.DataType.Kind <> dkOrdinal) then + raise EInvalidCast.Create('Ordinal expected'); + Result := IDataOrdinalValue(FDataValue); +end; + +function TDataType.TValue.AsRecord: IDataRecordValue; +begin + if (FDataValue.DataType.Kind <> dkRecord) then + raise EInvalidCast.Create('Record expected'); + Result := IDataRecordValue(FDataValue); +end; + +function TDataType.TValue.AsText: IDataTextValue; +begin + if (FDataValue.DataType.Kind <> dkText) then + raise EInvalidCast.Create('Text expected'); + Result := IDataTextValue(FDataValue); +end; + +function TDataType.TValue.AsTimestamp: IDataTimestampValue; +begin + if (FDataValue.DataType.Kind <> dkTimestamp) then + raise EInvalidCast.Create('Timestamp expected'); + Result := IDataTimestampValue(FDataValue); +end; + +function TDataType.TValue.AsTuple: IDataTupleValue; +begin + if (FDataValue.DataType.Kind <> dkTuple) then + raise EInvalidCast.Create('Tuple expected'); + Result := IDataTupleValue(FDataValue); +end; + +function TDataType.TValue.AsVoid: IDataVoidValue; +begin + if (FDataValue.DataType.Kind <> dkVoid) then + raise EInvalidCast.Create('Void expected'); + Result := IDataVoidValue(FDataValue); end; function TDataType.TValue.GetDataType: IDataType; @@ -1326,54 +1101,59 @@ begin Result := A.FDataValue; end; +class operator TDataType.TValue.Implicit(const A: IDataArrayValue): TDataType.TValue; +begin + Result.FDataValue := A; +end; + +class operator TDataType.TValue.Implicit(const A: IDataEnumValue): TDataType.TValue; +begin + Result.FDataValue := A; +end; + +class operator TDataType.TValue.Implicit(const A: IDataFloatValue): TDataType.TValue; +begin + Result.FDataValue := A; +end; + +class operator TDataType.TValue.Implicit(const A: IDataMethodValue): TDataType.TValue; +begin + Result.FDataValue := A; +end; + +class operator TDataType.TValue.Implicit(const A: IDataOrdinalValue): TDataType.TValue; +begin + Result.FDataValue := A; +end; + +class operator TDataType.TValue.Implicit(const A: IDataRecordValue): TDataType.TValue; +begin + Result.FDataValue := A; +end; + +class operator TDataType.TValue.Implicit(const A: IDataTextValue): TDataType.TValue; +begin + Result.FDataValue := A; +end; + +class operator TDataType.TValue.Implicit(const A: IDataTimestampValue): TDataType.TValue; +begin + Result.FDataValue := A; +end; + +class operator TDataType.TValue.Implicit(const A: IDataTupleValue): TDataType.TValue; +begin + Result.FDataValue := A; +end; + class operator TDataType.TValue.Implicit(const A: IDataValue): TDataType.TValue; begin Result.FDataValue := A; end; -class operator TDataType.TValue.Implicit(const A: TDataOrdinalValue): TDataType.TValue; +class operator TDataType.TValue.Implicit(const A: IDataVoidValue): TDataType.TValue; begin - Result.FDataValue := A.FOrdinalValue; -end; - -class operator TDataType.TValue.Implicit(const A: TDataFloatValue): TDataType.TValue; -begin - Result.FDataValue := A.FFloatValue; -end; - -class operator TDataType.TValue.Implicit(const A: TDataTextValue): TDataType.TValue; -begin - Result.FDataValue := A.FTextValue; -end; - -class operator TDataType.TValue.Implicit(const A: TDataTimestampValue): TDataType.TValue; -begin - Result.FDataValue := A.FTimestampValue; -end; - -class operator TDataType.TValue.Implicit(const A: TDataEnumValue): TDataType.TValue; -begin - Result.FDataValue := A.FEnumValue; -end; - -class operator TDataType.TValue.Implicit(const A: TDataMethodValue): TDataType.TValue; -begin - Result.FDataValue := A.FMethodValue; -end; - -class operator TDataType.TValue.Implicit(const A: TDataRecordValue): TDataType.TValue; -begin - Result.FDataValue := A.FRecordValue; -end; - -class operator TDataType.TValue.Implicit(const A: TDataTupleValue): TDataType.TValue; -begin - Result.FDataValue := A.FTupleValue; -end; - -class operator TDataType.TValue.Implicit(const A: TDataArrayValue): TDataType.TValue; -begin - Result.FDataValue := A.FArrayValue; + Result.FDataValue := A; end; end. diff --git a/Src/Data/TestDataTypes.pas b/Src/Data/TestDataTypes.pas index c32f888..a24f3a0 100644 --- a/Src/Data/TestDataTypes.pas +++ b/Src/Data/TestDataTypes.pas @@ -54,9 +54,9 @@ var intType: TDataType.TOrdinal; floatType: TDataType.TFloat; personType1, personType2, otherType: TDataType.TRecord; - personValue: TDataRecordValue; - idValue: TDataOrdinalValue; - floatValue: TDataFloatValue; + personValue: IDataRecordValue; + idValue: IDataOrdinalValue; + floatValue: IDataFloatValue; begin // This test covers the optimized implementation for 2 fields. // --- 1. Setup: Define base types and a record structure --- @@ -88,8 +88,8 @@ begin // --- 3. Test Value Creation and Access --- personValue := personType1.CreateValue([TDataType.FromOrdinal(123), TDataType.FromFloat(45.67)]); - Assert.IsNotNull(IDataRecordValue(personValue), 'RecordValue should be created'); - Assert.AreSame(IDataRecordType(personType1), IDataRecordValue(personValue).DataType, 'Value should have the correct data type'); + Assert.IsNotNull(personValue, 'RecordValue should be created'); + Assert.AreSame(IDataRecordType(personType1), personValue.DataType, 'Value should have the correct data type'); // Access by index idValue := TDataType.TValue(personValue.Items[0]).AsOrdinal; @@ -131,7 +131,7 @@ end; procedure TMyTestObject.TestRecords_Generic; var dataType: TDataType.TRecord; - dataValue: TDataRecordValue; + dataValue: IDataRecordValue; begin // Test the generic implementation for records with > 2 fields. dataType := @@ -144,19 +144,19 @@ begin ); dataValue := dataType.CreateValue([TDataType.FromOrdinal(1), TDataType.FromText('two'), TDataType.FromFloat(3.0)]); - Assert.IsNotNull(IDataRecordValue(dataValue), 'Generic record value should be created'); + Assert.IsNotNull(dataValue, 'Generic record value should be created'); Assert.AreEqual(3, dataType.FieldCount, 'Generic record should have 3 fields'); Assert.AreEqual(Int64(1), TDataType.TValue(dataValue.Items[0]).AsOrdinal.Value, 'Field A is incorrect'); Assert.AreEqual('two', TDataType.TValue(dataValue.Items[1]).AsText.Value, 'Field B is incorrect'); Assert.AreEqual(3.0, TDataType.TValue(dataValue.Items[2]).AsFloat.Value, 'Field C is incorrect'); - Assert.AreEqual('', IDataRecordValue(dataValue).AsString, 'Generic record AsString is incorrect'); + Assert.AreEqual('', dataValue.AsString, 'Generic record AsString is incorrect'); end; procedure TMyTestObject.TestTuples; var - intValue: TDataOrdinalValue; - floatValue: TDataFloatValue; - tuple1, tuple2, tuple3: TDataTupleValue; + intValue: IDataOrdinalValue; + floatValue: IDataFloatValue; + tuple1, tuple2, tuple3: IDataTupleValue; type1, type2, type3: IDataType; // Keep as interface to test AreSame on the raw interface pointer begin // This test covers optimized implementations for 1 and 2 elements. @@ -167,10 +167,10 @@ begin // --- 2. Test Value Creation and basic properties --- tuple1 := TDataType.FromTuple([intValue, floatValue]); - Assert.IsNotNull(IDataTupleValue(tuple1), 'Tuple value should be created'); + Assert.IsNotNull(tuple1, 'Tuple value should be created'); Assert.AreEqual(2, tuple1.ItemCount, 'ItemCount should be on the value'); - Assert.AreSame(IDataValue(intValue), tuple1.Items[0], 'Item at index 0 is incorrect'); - Assert.AreSame(IDataValue(floatValue), tuple1.Items[1], 'Item at index 1 is incorrect'); + Assert.AreSame(intValue, tuple1.Items[0], 'Item at index 0 is incorrect'); + Assert.AreSame(floatValue, tuple1.Items[1], 'Item at index 1 is incorrect'); // --- 3. Test Singleton Type Behavior --- // Create more tuples with different structures @@ -178,9 +178,9 @@ begin tuple3 := TDataType.FromTuple([intValue]); // Access the DataType via the underlying interface - type1 := IDataValue(tuple1).DataType; - type2 := IDataValue(tuple2).DataType; - type3 := IDataValue(tuple3).DataType; + type1 := tuple1.DataType; + type2 := tuple2.DataType; + type3 := tuple3.DataType; Assert.IsNotNull(type1, 'DataType interface should be accessible'); Assert.AreEqual('Tuple', type1.Name, 'The type name for all tuples should be Tuple'); @@ -192,7 +192,7 @@ end; procedure TMyTestObject.TestTuples_Generic; var - tupleValue: TDataTupleValue; + tupleValue: IDataTupleValue; begin // Test the generic implementation for tuples with > 5 elements. tupleValue := @@ -207,10 +207,10 @@ begin ] ); - Assert.IsNotNull(IDataTupleValue(tupleValue), 'Generic tuple value should be created'); + Assert.IsNotNull(tupleValue, 'Generic tuple value should be created'); Assert.AreEqual(6, tupleValue.ItemCount, 'Generic tuple should have 6 items'); Assert.AreEqual(Int64(6), TDataType.TValue(tupleValue.Items[5]).AsOrdinal.Value, 'Last item is incorrect'); - Assert.AreEqual('(1, 2, 3, 4, 5, 6)', IDataTupleValue(tupleValue).AsString, 'Generic tuple AsString is incorrect'); + Assert.AreEqual('(1, 2, 3, 4, 5, 6)', tupleValue.AsString, 'Generic tuple AsString is incorrect'); end; procedure TMyTestObject.TestArrays; @@ -219,8 +219,8 @@ var floatType: TDataType.TFloat; intArrayType1, intArrayType2: TDataType.TArray; floatArrayType: TDataType.TArray; - arrayValue: TDataArrayValue; - v1, v2: TDataOrdinalValue; + arrayValue: IDataArrayValue; + v1, v2: IDataOrdinalValue; begin // --- 1. Setup --- intType := TDataType.Ordinal; @@ -251,7 +251,7 @@ begin v2 := TDataType.FromOrdinal(20); arrayValue := intArrayType1.CreateValue([v1, v2]); - Assert.IsNotNull(IDataArrayValue(arrayValue), 'ArrayValue should be created'); + Assert.IsNotNull(arrayValue, 'ArrayValue should be created'); Assert.AreEqual(2, arrayValue.ElementCount, 'ElementCount should be 2'); // Access items and check values @@ -277,36 +277,36 @@ end; procedure TMyTestObject.TestArrays_OptimizedAndGeneric; var arrayType: TDataType.TArray; - empty1, empty2, single, generic: TDataArrayValue; + empty1, empty2, single, generic: IDataArrayValue; begin arrayType := TDataType.ArrayOf(TDataType.Ordinal); // Test optimized path for 0 elements (cached singleton per type) empty1 := arrayType.CreateValue([]); empty2 := arrayType.CreateValue([]); - Assert.IsNotNull(IDataArrayValue(empty1), 'Empty array value should be created'); - Assert.AreSame(IDataArrayValue(empty1), IDataArrayValue(empty2), 'Empty array value should be cached and reused'); + Assert.IsNotNull(empty1, 'Empty array value should be created'); + Assert.AreSame(empty1, empty2, 'Empty array value should be cached and reused'); Assert.AreEqual(0, empty1.ElementCount, 'Empty array should have 0 elements'); - Assert.AreEqual('[]', IDataArrayValue(empty1).AsString, 'Empty array AsString is incorrect'); + Assert.AreEqual('[]', empty1.AsString, 'Empty array AsString is incorrect'); // Test optimized path for 1 element single := arrayType.CreateValue([TDataType.FromOrdinal(42)]); - Assert.IsNotNull(IDataArrayValue(single), 'Single element array should be created'); + Assert.IsNotNull(single, 'Single element array should be created'); Assert.AreEqual(1, single.ElementCount, 'Single element array should have 1 element'); Assert.AreEqual(Int64(42), TDataType.TValue(single.Items[0]).AsOrdinal.Value, 'Single element value is incorrect'); - Assert.AreEqual('[42]', IDataArrayValue(single).AsString, 'Single element array AsString is incorrect'); + Assert.AreEqual('[42]', single.AsString, 'Single element array AsString is incorrect'); // Test generic path for > 1 elements generic := arrayType.CreateValue([TDataType.FromOrdinal(1), TDataType.FromOrdinal(2), TDataType.FromOrdinal(3)]); - Assert.IsNotNull(IDataArrayValue(generic), 'Generic array should be created'); + Assert.IsNotNull(generic, 'Generic array should be created'); Assert.AreEqual(3, generic.ElementCount, 'Generic array should have 3 elements'); - Assert.AreEqual('[1, 2, 3]', IDataArrayValue(generic).AsString, 'Generic array AsString is incorrect'); + Assert.AreEqual('[1, 2, 3]', generic.AsString, 'Generic array AsString is incorrect'); end; procedure TMyTestObject.TestTexts; var textType: TDataType.TText; - textValue1, textValue2: TDataTextValue; + textValue1, textValue2: IDataTextValue; dataValue: IDataValue; begin // --- 1. Test Type Creation --- @@ -319,8 +319,8 @@ begin // --- 2. Test Value Creation and Access --- textValue1 := TDataType.FromText('Hello World'); - Assert.IsNotNull(IDataTextValue(textValue1), 'TextValue should be created'); - Assert.AreSame(IDataType(textType), IDataTextValue(textValue1).DataType, 'Value should have the correct data type'); + Assert.IsNotNull(textValue1, 'TextValue should be created'); + Assert.AreSame(IDataType(textType), textValue1.DataType, 'Value should have the correct data type'); Assert.AreEqual('Hello World', textValue1.Value, 'Value should be ''Hello World'''); // Test another text value @@ -342,49 +342,49 @@ end; procedure TMyTestObject.TestTexts_OptimizedEmpty; var - empty1, empty2: TDataTextValue; + empty1, empty2: IDataTextValue; begin // Test the singleton implementation for the empty string. empty1 := TDataType.FromText(''); empty2 := TDataType.FromText(''); - Assert.IsNotNull(IDataTextValue(empty1), 'Empty text value should be created'); - Assert.AreSame(IDataTextValue(empty1), IDataTextValue(empty2), 'Empty text value should be a singleton'); + Assert.IsNotNull(empty1, 'Empty text value should be created'); + Assert.AreSame(empty1, empty2, 'Empty text value should be a singleton'); Assert.AreEqual('', empty1.Value, 'Value of empty text should be empty'); - Assert.AreEqual('', IDataTextValue(empty1).AsString, 'AsString of empty text should be empty'); + Assert.AreEqual('', empty1.AsString, 'AsString of empty text should be empty'); end; procedure TMyTestObject.TestFloats_OptimizedAndGeneric; var - zero1, zero2, nan1, nan2, generic: TDataFloatValue; + zero1, zero2, nan1, nan2, generic: IDataFloatValue; begin // Test singleton for 0.0 zero1 := TDataType.FromFloat(0.0); zero2 := TDataType.FromFloat(0.0); - Assert.IsNotNull(IDataFloatValue(zero1), 'Zero float should be created'); - Assert.AreSame(IDataFloatValue(zero1), IDataFloatValue(zero2), 'Zero float should be a singleton'); + Assert.IsNotNull(zero1, 'Zero float should be created'); + Assert.AreSame(zero1, zero2, 'Zero float should be a singleton'); Assert.AreEqual(0.0, zero1.Value, 'Value of zero float is incorrect'); // Test singleton for NaN nan1 := TDataType.FromFloat(NaN); nan2 := TDataType.FromFloat(NaN); - Assert.IsNotNull(IDataFloatValue(nan1), 'NaN float should be created'); - Assert.AreSame(IDataFloatValue(nan1), IDataFloatValue(nan2), 'NaN float should be a singleton'); + Assert.IsNotNull(nan1, 'NaN float should be created'); + Assert.AreSame(nan1, nan2, 'NaN float should be a singleton'); Assert.IsTrue(IsNaN(nan1.Value), 'Value of NaN float should be NaN'); - Assert.AreEqual('NaN', IDataFloatValue(nan1).AsString, 'NaN AsString is incorrect'); + Assert.AreEqual('NaN', nan1.AsString, 'NaN AsString is incorrect'); // Test generic path generic := TDataType.FromFloat(123.45); - Assert.IsNotNull(IDataFloatValue(generic), 'Generic float should be created'); - Assert.AreNotSame(IDataFloatValue(zero1), IDataFloatValue(generic), 'Generic float should not be the zero singleton'); - Assert.AreNotSame(IDataFloatValue(nan1), IDataFloatValue(generic), 'Generic float should not be the NaN singleton'); + Assert.IsNotNull(generic, 'Generic float should be created'); + Assert.AreNotSame(zero1, generic, 'Generic float should not be the zero singleton'); + Assert.AreNotSame(nan1, generic, 'Generic float should not be the NaN singleton'); Assert.AreEqual(123.45, generic.Value, 'Value of generic float is incorrect'); end; procedure TMyTestObject.TestTimestamps; var tsType: TDataType.TTimestamp; - tsValue1, tsValue2: TDataTimestampValue; + tsValue1, tsValue2: IDataTimestampValue; dataValue: IDataValue; now: TDateTime; begin @@ -399,8 +399,8 @@ begin now := System.Sysutils.Now; tsValue1 := TDataType.FromTimestamp(now); - Assert.IsNotNull(IDataTimestampValue(tsValue1), 'TimestampValue should be created'); - Assert.AreSame(IDataType(tsType), IDataTimestampValue(tsValue1).DataType, 'Value should have the correct data type'); + Assert.IsNotNull(tsValue1, 'TimestampValue should be created'); + Assert.AreSame(IDataType(tsType), tsValue1.DataType, 'Value should have the correct data type'); Assert.AreEqual(now, tsValue1.Value, 'Value should be the same'); // Test another text value @@ -423,7 +423,7 @@ end; procedure TMyTestObject.TestEnums; var colorType: TDataType.TEnum; - red, green, blue: TDataEnumValue; + red, green, blue: IDataEnumValue; begin // --- 1. Test Type Creation --- colorType := TDataType.EnumOf('Color', ['Red', 'Green', 'Blue']); @@ -443,15 +443,15 @@ begin green := colorType.CreateValue('Green'); blue := colorType.CreateValue(2); - Assert.IsNotNull(IDataEnumValue(red), 'EnumValue from index should be created'); - Assert.AreSame(IDataType(colorType), IDataEnumValue(red).DataType, 'Red should have the correct data type'); + Assert.IsNotNull(red, 'EnumValue from index should be created'); + Assert.AreSame(IDataType(colorType), red.DataType, 'Red should have the correct data type'); Assert.AreEqual(0, red.Value, 'Value of Red should be 0'); - Assert.AreEqual('Red', IDataEnumValue(red).AsString, 'AsText of Red should be Red'); + Assert.AreEqual('Red', red.AsString, 'AsText of Red should be Red'); - Assert.IsNotNull(IDataEnumValue(green), 'EnumValue from identifier should be created'); - Assert.AreSame(IDataType(colorType), IDataEnumValue(green).DataType, 'Green should have the correct data type'); + Assert.IsNotNull(green, 'EnumValue from identifier should be created'); + Assert.AreSame(IDataType(colorType), green.DataType, 'Green should have the correct data type'); Assert.AreEqual(1, green.Value, 'Value of Green should be 1'); - Assert.AreEqual('Green', IDataEnumValue(green).AsString, 'AsText of Green should be Green'); + Assert.AreEqual('Green', green.AsString, 'AsText of Green should be Green'); Assert.AreEqual(2, blue.Value, 'Value of Blue should be 2'); @@ -477,14 +477,14 @@ end; procedure TMyTestObject.TestAsString; var - ordinalValue: TDataOrdinalValue; - floatValue: TDataFloatValue; - textValue: TDataTextValue; - tsValue: TDataTimestampValue; - enumValue: TDataEnumValue; - arrayValue: TDataArrayValue; - recordValue: TDataRecordValue; - tupleValue: TDataTupleValue; + ordinalValue: IDataOrdinalValue; + floatValue: IDataFloatValue; + textValue: IDataTextValue; + tsValue: IDataTimestampValue; + enumValue: IDataEnumValue; + arrayValue: IDataArrayValue; + recordValue: IDataRecordValue; + tupleValue: IDataTupleValue; colorType: TDataType.TEnum; personType: TDataType.TRecord; intArrayType: TDataType.TArray; @@ -492,39 +492,39 @@ var begin // Ordinal ordinalValue := TDataType.FromOrdinal(123); - Assert.AreEqual('123', IDataOrdinalValue(ordinalValue).AsString, 'Ordinal AsString incorrect'); + Assert.AreEqual('123', ordinalValue.AsString, 'Ordinal AsString incorrect'); // Float floatValue := TDataType.FromFloat(45.67); - Assert.AreEqual(FloatToStr(45.67), IDataFloatValue(floatValue).AsString, 'Float AsString incorrect'); + Assert.AreEqual(FloatToStr(45.67), floatValue.AsString, 'Float AsString incorrect'); // Text textValue := TDataType.FromText('Hello'); - Assert.AreEqual('Hello', IDataTextValue(textValue).AsString, 'Text AsString incorrect'); + Assert.AreEqual('Hello', textValue.AsString, 'Text AsString incorrect'); // Timestamp now := System.Sysutils.Now; tsValue := TDataType.FromTimestamp(now); - Assert.AreEqual(DateTimeToStr(now), IDataTimestampValue(tsValue).AsString, 'Timestamp AsString incorrect'); + Assert.AreEqual(DateTimeToStr(now), tsValue.AsString, 'Timestamp AsString incorrect'); // Enum colorType := TDataType.EnumOf('Color', ['Red', 'Green', 'Blue']); enumValue := colorType.CreateValue('Green'); - Assert.AreEqual('Green', IDataEnumValue(enumValue).AsString, 'Enum AsString incorrect'); + Assert.AreEqual('Green', enumValue.AsString, 'Enum AsString incorrect'); // Array intArrayType := TDataType.ArrayOf(TDataType.Ordinal); arrayValue := intArrayType.CreateValue([TDataType.FromOrdinal(1), TDataType.FromOrdinal(2)]); - Assert.AreEqual('[1, 2]', IDataArrayValue(arrayValue).AsString, 'Array AsString incorrect'); + Assert.AreEqual('[1, 2]', arrayValue.AsString, 'Array AsString incorrect'); // Record personType := TDataType.RecordOf([TRecordField.Create('ID', TDataType.Ordinal), TRecordField.Create('Name', TDataType.Text)]); recordValue := personType.CreateValue([TDataType.FromOrdinal(1), TDataType.FromText('Bob')]); - Assert.AreEqual('', IDataRecordValue(recordValue).AsString, 'Record AsString incorrect'); + Assert.AreEqual('', recordValue.AsString, 'Record AsString incorrect'); // Tuple tupleValue := TDataType.FromTuple([TDataType.FromOrdinal(10), TDataType.FromText('Tuple')]); - Assert.AreEqual('(10, Tuple)', IDataTupleValue(tupleValue).AsString, 'Tuple AsString incorrect'); + Assert.AreEqual('(10, Tuple)', tupleValue.AsString, 'Tuple AsString incorrect'); end; procedure TMyTestObject.TestAsTValue; @@ -624,8 +624,8 @@ var textType: TDataType.TText; methodType1, methodType2, otherMethodType: TDataType.TMethod; myFunc: TDataType.TMethod.TProc; - methodValue: TDataMethodValue; - inputValue: TDataOrdinalValue; + methodValue: IDataMethodValue; + inputValue: IDataOrdinalValue; resultValue: IDataValue; tv: TValue; begin @@ -662,7 +662,7 @@ begin myFunc := function(const AValue: TDataType.TValue): TDataType.TValue var - ordinalValue: TDataOrdinalValue; + ordinalValue: IDataOrdinalValue; val: Int64; begin ordinalValue := AValue.AsOrdinal; @@ -671,8 +671,8 @@ begin end; methodValue := TDataType.FromMethod(methodType1, myFunc); - Assert.IsNotNull(IDataMethodValue(methodValue), 'MethodValue should be created'); - Assert.AreSame(IDataType(methodType1), IDataMethodValue(methodValue).DataType, 'Value should have the correct data type'); + Assert.IsNotNull(methodValue, 'MethodValue should be created'); + Assert.AreSame(IDataType(methodType1), methodValue.DataType, 'Value should have the correct data type'); // --- 4. Test Execution (Simulated) --- inputValue := TDataType.FromOrdinal(42); @@ -684,9 +684,9 @@ begin Assert.AreEqual('42', TDataType.TValue(resultValue).AsText.Value, 'Result value content is incorrect'); // --- 5. Test AsString and AsTValue --- - Assert.AreEqual('', IDataMethodValue(methodValue).AsString, 'Method AsString is incorrect'); + Assert.AreEqual('', methodValue.AsString, 'Method AsString is incorrect'); - tv := IDataMethodValue(methodValue).AsTValue; + tv := methodValue.AsTValue; Assert.IsFalse(tv.IsEmpty, 'Method TValue should not be empty'); Assert.AreEqual(tkInterface, tv.Kind, 'TValue kind for a TMethodProc should be tkInterface, as it is a reference-to-function'); Assert.IsTrue(TypeInfo(TDataMethodProc) = tv.TypeInfo, 'TValue should hold TMethodProc type info'); diff --git a/Src/Myc.Trade.Indicators.Common.pas b/Src/Myc.Trade.Indicators.Common.pas index b06eb2a..71999cf 100644 --- a/Src/Myc.Trade.Indicators.Common.pas +++ b/Src/Myc.Trade.Indicators.Common.pas @@ -21,7 +21,7 @@ type TSMA = class strict private class var - FFactory: TDataMethodValue; + FFactory: IDataMethodValue; class constructor CreateClass; public type @@ -39,7 +39,7 @@ type class function CreateSMA(Period: Integer): TConvertFunc; static; // Provides the factory method for this indicator as a data value. - class property Factory: TDataMethodValue read FFactory; + class property Factory: IDataMethodValue read FFactory; end; [IndicatorName('EMA', 'Exponential Moving Average')] @@ -47,7 +47,7 @@ type TEMA = class strict private class var - FFactory: TDataMethodValue; + FFactory: IDataMethodValue; class constructor CreateClass; public type @@ -64,7 +64,7 @@ type class function CreateFactory: TIndicatorFactoryProc; static; class function CreateEMA(Period: Integer): TConvertFunc; static; // Provides the factory method for this indicator as a data value. - class property Factory: TDataMethodValue read FFactory; + class property Factory: IDataMethodValue read FFactory; end; [IndicatorName('WMA', 'Weighted Moving Average')] @@ -72,7 +72,7 @@ type TWMA = class strict private class var - FFactory: TDataMethodValue; + FFactory: IDataMethodValue; class constructor CreateClass; public type @@ -89,7 +89,7 @@ type class function CreateFactory: TIndicatorFactoryProc; static; class function CreateWMA(Period: Integer): TConvertFunc; static; // Provides the factory method for this indicator as a data value. - class property Factory: TDataMethodValue read FFactory; + class property Factory: IDataMethodValue read FFactory; end; [IndicatorName('HMA', 'Hull Moving Average')] @@ -97,7 +97,7 @@ type THMA = class strict private class var - FFactory: TDataMethodValue; + FFactory: IDataMethodValue; class constructor CreateClass; public type @@ -114,7 +114,7 @@ type class function CreateFactory: TIndicatorFactoryProc; static; class function CreateHMA(Period: Integer): TConvertFunc; static; // Provides the factory method for this indicator as a data value. - class property Factory: TDataMethodValue read FFactory; + class property Factory: IDataMethodValue read FFactory; end; [IndicatorName('RSI', 'Relative Strength Index')] @@ -122,7 +122,7 @@ type TRSI = class strict private class var - FFactory: TDataMethodValue; + FFactory: IDataMethodValue; class constructor CreateClass; public type @@ -139,7 +139,7 @@ type class function CreateFactory: TIndicatorFactoryProc; static; class function CreateRSI(Period: Integer): TConvertFunc; static; // Provides the factory method for this indicator as a data value. - class property Factory: TDataMethodValue read FFactory; + class property Factory: IDataMethodValue read FFactory; end; [IndicatorName('MACD', 'Moving Average Convergence Divergence')] @@ -147,7 +147,7 @@ type TMACD = class strict private class var - FFactory: TDataMethodValue; + FFactory: IDataMethodValue; class constructor CreateClass; public type @@ -173,7 +173,7 @@ type EmaSignal: TConvertFunc ): TConvertFunc; overload; static; // Provides the factory method for this indicator as a data value. - class property Factory: TDataMethodValue read FFactory; + class property Factory: IDataMethodValue read FFactory; end; [IndicatorName('Stoch', 'Stochastic Oscillator')] @@ -181,7 +181,7 @@ type TStochastic = class strict private class var - FFactory: TDataMethodValue; + FFactory: IDataMethodValue; class constructor CreateClass; public type @@ -205,7 +205,7 @@ type const SmaD: TConvertFunc ): TConvertFunc; overload; static; // Provides the factory method for this indicator as a data value. - class property Factory: TDataMethodValue read FFactory; + class property Factory: IDataMethodValue read FFactory; end; [IndicatorName('StdDev', 'Standard Deviation')] @@ -213,7 +213,7 @@ type TStdDev = class strict private class var - FFactory: TDataMethodValue; + FFactory: IDataMethodValue; class constructor CreateClass; public type @@ -230,7 +230,7 @@ type class function CreateFactory: TIndicatorFactoryProc; static; class function CreateStdDev(Period: Integer): TConvertFunc; static; // Provides the factory method for this indicator as a data value. - class property Factory: TDataMethodValue read FFactory; + class property Factory: IDataMethodValue read FFactory; end; [IndicatorName('BB', 'Bollinger Bands')] @@ -238,7 +238,7 @@ type TBollingerBands = class strict private class var - FFactory: TDataMethodValue; + FFactory: IDataMethodValue; class constructor CreateClass; public type @@ -258,7 +258,7 @@ type class function CreateFactory: TIndicatorFactoryProc; static; class function CreateBollingerBands(Period: Integer; Multiplier: Double): TConvertFunc; static; // Provides the factory method for this indicator as a data value. - class property Factory: TDataMethodValue read FFactory; + class property Factory: IDataMethodValue read FFactory; end; [IndicatorName('ATR', 'Average True Range')] @@ -266,7 +266,7 @@ type TATR = class strict private class var - FFactory: TDataMethodValue; + FFactory: IDataMethodValue; class constructor CreateClass; public type @@ -284,7 +284,7 @@ type class function CreateATR(Period: Integer): TConvertFunc; overload; static; class function CreateATR(const MovAvgTR: TConvertFunc): TConvertFunc; overload; static; // Provides the factory method for this indicator as a data value. - class property Factory: TDataMethodValue read FFactory; + class property Factory: IDataMethodValue read FFactory; end; [IndicatorName('KC', 'Keltner Channels')] @@ -292,7 +292,7 @@ type TKeltnerChannels = class strict private class var - FFactory: TDataMethodValue; + FFactory: IDataMethodValue; class constructor CreateClass; public type @@ -317,7 +317,7 @@ type Multiplier: Double ): TConvertFunc; overload; static; // Provides the factory method for this indicator as a data value. - class property Factory: TDataMethodValue read FFactory; + class property Factory: IDataMethodValue read FFactory; end; [IndicatorName('Mean', 'Mean Value')] @@ -325,7 +325,7 @@ type TMean = class strict private class var - FFactory: TDataMethodValue; + FFactory: IDataMethodValue; class constructor CreateClass; public type @@ -341,7 +341,7 @@ type class function CreateFactory: TIndicatorFactoryProc; static; class function CreateMean: TConvertFunc, Double>; static; // Provides the factory method for this indicator as a data value. - class property Factory: TDataMethodValue read FFactory; + class property Factory: IDataMethodValue read FFactory; end; implementation @@ -819,7 +819,7 @@ begin factoryMethodType.CreateValue( function(const Params: TDataType.TValue): TDataType.TValue var - paramsRec: TDataRecordValue; + paramsRec: IDataRecordValue; begin paramsRec := Params.AsRecord; var MACD := @@ -985,7 +985,7 @@ begin factoryMethodType.CreateValue( function(const Params: TDataType.TValue): TDataType.TValue var - paramsRec: TDataRecordValue; + paramsRec: IDataRecordValue; begin paramsRec := Params.AsRecord; var Stochastic := @@ -998,7 +998,7 @@ begin indicatorMethodType.CreateValue( function(const Args: TDataType.TValue): TDataType.TValue var - ohlcRec: TDataRecordValue; + ohlcRec: IDataRecordValue; ohlcVal: TOhlcItem; begin ohlcRec := Args.AsRecord; @@ -1236,7 +1236,7 @@ begin factoryMethodType.CreateValue( function(const Params: TDataType.TValue): TDataType.TValue var - paramsRec: TDataRecordValue; + paramsRec: IDataRecordValue; begin paramsRec := Params.AsRecord; var BollingerBands := @@ -1339,7 +1339,7 @@ begin indicatorMethodType.CreateValue( function(const Args: TDataType.TValue): TDataType.TValue var - ohlcRec: TDataRecordValue; + ohlcRec: IDataRecordValue; ohlcVal: TOhlcItem; begin ohlcRec := Args.AsRecord; @@ -1433,7 +1433,7 @@ begin factoryMethodType.CreateValue( function(const Params: TDataType.TValue): TDataType.TValue var - paramsRec: TDataRecordValue; + paramsRec: IDataRecordValue; begin paramsRec := Params.AsRecord; var KeltnerChannels := @@ -1446,7 +1446,7 @@ begin indicatorMethodType.CreateValue( function(const Args: TDataType.TValue): TDataType.TValue var - ohlcRec: TDataRecordValue; + ohlcRec: IDataRecordValue; ohlcVal: TOhlcItem; begin ohlcRec := Args.AsRecord; @@ -1526,12 +1526,11 @@ end; class constructor TMean.CreateClass; begin - var paramsType := TDataType.RecordOf([]); var argsType := TDataType.ArrayOf(TDataType.Float); var resultType := TDataType.Float; var indicatorMethodType := TDataType.MethodOf(argsType, resultType); - var factoryMethodType := TDataType.MethodOf(paramsType, indicatorMethodType); + var factoryMethodType := TDataType.MethodOf(TDataType.Void, indicatorMethodType); FFactory := factoryMethodType.CreateValue( @@ -1543,7 +1542,7 @@ begin function(const Args: TDataType.TValue): TDataType.TValue var i: Integer; - valuesArray: TDataArrayValue; + valuesArray: IDataArrayValue; values: TArray; begin valuesArray := Args.AsArray; diff --git a/Test/MycTests.dpr b/Test/MycTests.dpr index a63bd06..b6e966b 100644 --- a/Test/MycTests.dpr +++ b/Test/MycTests.dpr @@ -31,7 +31,8 @@ uses Myc.Data.Types.Float in 'Myc.Data.Types.Float.pas', Myc.Data.Types.Arrays in 'Myc.Data.Types.Arrays.pas', TestDataTypes in '..\Src\Data\TestDataTypes.pas', - Myc.Data.Types.Method in '..\Src\Data\Myc.Data.Types.Method.pas'; + Myc.Data.Types.Method in '..\Src\Data\Myc.Data.Types.Method.pas', + Myc.Data.Types.Void in '..\Src\Data\Myc.Data.Types.Void.pas'; { keep comment here to protect the following conditional from being removed by the IDE when adding a unit } {$IFNDEF TESTINSIGHT} diff --git a/Test/MycTests.dproj b/Test/MycTests.dproj index e90f0f7..a642c05 100644 --- a/Test/MycTests.dproj +++ b/Test/MycTests.dproj @@ -133,6 +133,7 @@ $(PreBuildEvent)]]> + Base