{ +-------------------------------------------------------------+ } { | | } { | GM-Software | } { | =========== | } { | | } { | Project: All Projects | } { | | } { | Description: Union value for multiple types like variant | } { | but smaller and faster. | } { | | } { | Copyright (C) - 2020 - Gerrit Moeller. | } { | | } { | Source code distributed under MIT license. | } { | | } { | See: https://www.gm-software.de | } { | | } { +-------------------------------------------------------------+ } {$INCLUDE GMCompilerSettings.inc} unit GMUnionValue; interface uses GMStrDef, Variants; type {$if FPC_FULLVERSION >= 30101} // SelfManaged Record size will be smaller because no additional pointers in the managed part of the reord are needed // SizeOf(RGMUnionValue) = 9 Byte on 32-Bit and 64-Bit platforms! {$define UseSelfManaged} {$define WithIntfType} {$endif} EGMUnionValueType = (uvtUnassigned, uvtNull, uvtString, uvtBoolean, uvtInt16, uvtInt32, uvtInt64, uvtDouble, uvtDateTime, uvtPointer{$ifdef WithIntfType},uvtInterface{$endif}); // // TStrType is meant to be a managed string data type like: UnicodeString, AnsiString, RawByteString, Utf8String or AnsiString(CP_XXXX) // WideString only works when UseSelfManaged is NOT defined // RGMGenericUnionValue<TStrType> = packed record private {$ifndef UseSelfManaged} StringValue: TStrType; {$ifdef WithIntfType} IntfValue: IUnknown; {$endif} {$endif} class operator Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): Boolean; class operator Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): Byte; class operator Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): SmallInt; class operator Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): Word; class operator Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): LongInt; class operator Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): LongWord; class operator Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): Int64; class operator Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): QWord; class operator Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): Pointer; class operator Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): Single; class operator Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): Double; class operator Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): TDateTime; class operator Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): UnicodeString; class operator Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): WideString; class operator Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): AnsiString; class operator Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): Utf8String; class operator Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): Variant; class operator Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): OleVariant; class operator Implicit(AValue: EGMUnionValueType): RGMGenericUnionValue<TStrType>; class operator Implicit(AValue: Boolean): RGMGenericUnionValue<TStrType>; class operator Implicit(AValue: SmallInt): RGMGenericUnionValue<TStrType>; class operator Implicit(AValue: LongInt): RGMGenericUnionValue<TStrType>; class operator Implicit(AValue: Int64): RGMGenericUnionValue<TStrType>; class operator Implicit(AValue: Double): RGMGenericUnionValue<TStrType>; class operator Implicit(AValue: TDateTime): RGMGenericUnionValue<TStrType>; class operator Implicit(AValue: Pointer): RGMGenericUnionValue<TStrType>; class operator Implicit(AValue: UnicodeString): RGMGenericUnionValue<TStrType>; class operator Implicit(AValue: WideString): RGMGenericUnionValue<TStrType>; class operator Implicit(AValue: AnsiString): RGMGenericUnionValue<TStrType>; class operator Implicit(AValue: Utf8String): RGMGenericUnionValue<TStrType>; class operator Implicit(AValue: Variant): RGMGenericUnionValue<TStrType>; class operator Implicit(AValue: OleVariant): RGMGenericUnionValue<TStrType>; procedure InternalAssignString(const AStrVal: TStrType); inline; {$ifdef WithIntfType} procedure InternalAssignIntf(const AIntfVal: IUnknown); inline; class operator Implicit(AValue: IUnknown): RGMGenericUnionValue<TStrType>; class operator Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): IUnknown; {$endif} public class operator Initialize(var AUnionValue: RGMGenericUnionValue<TStrType>); {$ifdef UseSelfManaged} class operator Finalize(var AUnionValue: RGMGenericUnionValue<TStrType>); class operator Copy(constref ASrc: RGMGenericUnionValue<TStrType>; var ADst: RGMGenericUnionValue<TStrType>); class operator AddRef(var ADst: RGMGenericUnionValue<TStrType>); {$endif} class operator Equal(const AValue1, AValue2: RGMGenericUnionValue<TStrType>): Boolean; class operator Equal(const AUnionValue: RGMGenericUnionValue<TStrType>; AValue: Int64): Boolean; class operator Equal(const AUnionValue: RGMGenericUnionValue<TStrType>; AValue: LongInt): Boolean; class operator Equal(const AUnionValue: RGMGenericUnionValue<TStrType>; AValue: Pointer): Boolean; {$ifdef WithIntfType} class operator Equal(const AUnionValue: RGMGenericUnionValue<TStrType>; AValue: IUnknown): Boolean; {$endif} class operator Equal(const AUnionValue: RGMGenericUnionValue<TStrType>; AValue: Double): Boolean; //class operator Equal(const AUnionValue: RGMGenericUnionValue<TStrType>; AValue: TDateTime): Boolean; class operator Equal(const AUnionValue: RGMGenericUnionValue<TStrType>; AValue: UnicodeString): Boolean; class operator Equal(const AUnionValue: RGMGenericUnionValue<TStrType>; AValue: WideString): Boolean; class operator Equal(const AUnionValue: RGMGenericUnionValue<TStrType>; AValue: AnsiString): Boolean; class operator Equal(const AUnionValue: RGMGenericUnionValue<TStrType>; AValue: Utf8String): Boolean; class operator NotEqual(const AValue1, AValue2: RGMGenericUnionValue<TStrType>): Boolean; class operator Add(const AValue1, AValue2: RGMGenericUnionValue<TStrType>): RGMGenericUnionValue<TStrType>; class operator Multiply(const AValue1, AValue2: RGMGenericUnionValue<TStrType>): RGMGenericUnionValue<TStrType>; class operator Divide(const AValue1, AValue2: RGMGenericUnionValue<TStrType>): RGMGenericUnionValue<TStrType>; class operator IntDivide(const AValue1, AValue2: RGMGenericUnionValue<TStrType>): RGMGenericUnionValue<TStrType>; class operator Modulus(const AValue1, AValue2: RGMGenericUnionValue<TStrType>): RGMGenericUnionValue<TStrType>; class operator LessThan(const AValue1, AValue2: RGMGenericUnionValue<TStrType>): Boolean; class operator GreaterThan(const AValue1, AValue2: RGMGenericUnionValue<TStrType>): Boolean; class operator LessThanOrEqual(const AValue1, AValue2: RGMGenericUnionValue<TStrType>): Boolean; class operator GreaterThanOrEqual(const AValue1, AValue2: RGMGenericUnionValue<TStrType>): Boolean; function IsNull: Boolean; function IsUnassigned: Boolean; function IsNullOrUnassigned: Boolean; function AsBoolean: Boolean; function AsInt16: SmallInt; function AsInt32: LongInt; function AsInt64: Int64; function AsDouble: Double; function AsDateTime: TDateTime; function AsString: TGMString; //function AsDisplayString: TGMString; function AsPointer: Pointer; {$ifdef WithIntfType} function AsInterface: IUnknown; {$endif} function AsBooleanDflt(const ADefaultValue: Boolean = False): Boolean; function AsInt16Dflt(const ADefaultValue: SmallInt = 0): SmallInt; function AsInt32Dflt(const ADefaultValue: LongInt = 0): LongInt; function AsInt64Dflt(const ADefaultValue: Int64 = 0): Int64; function AsDoubleDflt(const ADefaultValue: Double = 0.0): Double; function AsDateTimeDflt(const ADefaultValue: TDateTime = 0): TDateTime; function AsPointerDflt(const ADefaultValue: Pointer = nil): Pointer; function AsStringDflt(const ADefaultValue: TGMString = ''): TGMString; {$ifdef WithIntfType} function AsInterfaceDflt(const ADefaultValue: IUnknown = nil): IUnknown; {$endif} function ValueTypeName: TGMSTring; case ValueType: EGMUnionValueType of {$ifdef UseSelfManaged} uvtString: (StringValue: Pointer); {$ifdef WithIntfType} uvtInterface: (IntfValue: Pointer); {$endif} {$endif} uvtBoolean: (BoolValue: Boolean); uvtInt16: (Int16Value: SmallInt); uvtInt32: (Int32Value: LongInt); uvtInt64: (Int64Value: Int64); uvtDouble: (DoubleValue: Double); uvtDateTime: (DateTimeValue: TDateTime); uvtPointer: (PointerValue: Pointer); end; PGMUnionValue = ^RGMUnionValue; RGMUnionValue = RGMGenericUnionValue<TGMString>; IGMGetUnionValue = interface(IUnknown) ['{9BB4E638-DB7C-4583-9EE3-410E4FB0F5CB}'] function GetUnionValue: RGMUnionValue; property Value: RGMUnionValue read GetUnionValue; end; IGMGetSetUnionValue = interface(IGMGetUnionValue) ['{3A3129DF-850E-40DA-AEF0-945A0BF2539C}'] procedure SetUnionValue(const AValue: RGMUnionValue); property Value: RGMUnionValue read GetUnionValue write SetUnionValue; end; TGMUnionValToStrFunc = function (const AValue: RGMUnionValue): TGMString; // // To be used with GMNamesAndValuesAsString and GMSeparatedValues // function GMUnionValueAsString(const AValue: RGMUnionValue): TGMString; function GMUnionValueAsQuotedString(const AValue: RGMUnionValue): TGMString; function GMUnionValueTypeName(const AValueType: EGMUnionValueType): TGMString; function GMUnionValueAsType(const AValue: RGMUnionValue; const ADestType: EGMUnionValueType): RGMUnionValue; function GMUnionValueAsTypeDflt(const AValue: RGMUnionValue; const ADestType: EGMUnionValueType): RGMUnionValue; procedure RaiseExceptionFmt(const AMsg: TGMString = ''; const AObj: TObject = nil; const ARoutineName: TGMString = ''); resourcestring srValueConvertToErrFmt = 'Cannot convert union value of type %s to type %s'; srValueConvertFromErrFmt = 'Cannot convert from %s to union value'; implementation {$macro on} uses SysUtils, TypInfo, GMIntf, GMCommon; type XGMUnionValueConvertError = class(EGMException); resourcestring srValueTypeOutofBounds = 'UnionValue ValueType %d out of bounds, must be in [%d .. %d]'; function GMUnionValueTypeName(const AValueType: EGMUnionValueType): TGMString; begin // AValueType enum value out of bounds may happen if not proper initialized if GMIsInRange(Ord(AValueType), Ord(Low(AValueType)), Ord(High(AValueType))) then Result := GetEnumName(TypeInfo(EGMUnionValueType), Ord(AValueType)) else Result := GMFormat(srValueTypeOutofBounds, [Ord(AValueType), Low(AValueType), High(AValueType)]); end; function GMUnionValueAsString(const AValue: RGMUnionValue): TGMString; begin Result := AValue.AsStringDflt; end; function GMUnionValueAsQuotedString(const AValue: RGMUnionValue): TGMString; begin Result := GMQuote(GMUnionValueAsString(AValue), '"', '"'); end; function GMUnionValueAsType(const AValue: RGMUnionValue; const ADestType: EGMUnionValueType): RGMUnionValue; begin //Result := Default(RGMUnionValue); case ADestType of uvtUnassigned: Result := uvtUnassigned; uvtNull: Result := uvtNull; uvtString: Result := AValue.AsString; uvtBoolean: Result := AValue.AsBoolean; uvtInt16: Result := AValue.AsInt16; uvtInt32: Result := AValue.AsInt32; uvtInt64: Result := AValue.AsInt64; uvtDouble: Result := AValue.AsDouble; uvtDateTime: Result := AValue.AsDateTime; uvtPointer: Result := AValue.AsPointer; end; end; function GMUnionValueAsTypeDflt(const AValue: RGMUnionValue; const ADestType: EGMUnionValueType): RGMUnionValue; begin //Result := Default(RGMUnionValue); case ADestType of uvtUnassigned: Result := uvtUnassigned; uvtNull: Result := uvtNull; uvtString: Result := AValue.AsStringDflt; uvtBoolean: Result := AValue.AsBooleanDflt; uvtInt16: Result := AValue.AsInt16Dflt; uvtInt32: Result := AValue.AsInt32Dflt; uvtInt64: Result := AValue.AsInt64Dflt; uvtDouble: Result := AValue.AsDoubleDflt; uvtDateTime: Result := AValue.AsDateTimeDflt; uvtPointer: Result := AValue.AsPointerDflt; end; end; procedure RaiseExceptionFmt(const AMsg: TGMString = cDfltExceptionMsg; const AObj: TObject = nil; const ARoutineName: TGMString = cDfltRoutineName); //const ASeverityLevel: TGMSeverityLevel = svError; //const AHelpCtx: LongInt = cDfltHelpCtx); begin raise XGMUnionValueConvertError.ObjError(AMsg, AObj, ARoutineName); end; { --------------------------------------------------- } { ---- RGMGenericUnionValue<TStrType, TIntfType> ---- } { --------------------------------------------------- } //const // // cBoolInt: array [Boolean] of Int64 = (0, 1); moved to GMCommon unit // cBoolStr: array [Boolean] of TGMString = ('False', 'True'); moved to GMCommon unit {$ifdef UseSelfManaged} {$define StrTypeCasted:=TStrType} {$else} {$define StrTypeCasted:=} {$endif} class operator RGMGenericUnionValue<TStrType>.Initialize(var AUnionValue: RGMGenericUnionValue<TStrType>); begin FillByte(AUnionValue, SizeOf(AUnionValue), 0); //AUnionValue := Default(RGMGenericUnionValue<TStrType>); <- crashes in some cases because it calls finalize //AUnionValue.ValueType := uvtUnassigned; //AUnionValue.Int64Value := 0; //AUnionValue.DoubleValue := 0; end; procedure RGMGenericUnionValue<TStrType>.InternalAssignString(const AStrVal: TStrType); begin // Assumes Finalize() has been called before if ValueType <> uvtString then begin {$ifdef UseSelfManaged} StringValue := nil; {$endif} ValueType := uvtString; end; StrTypeCasted(StringValue) := AStrVal; //vfGMTrace('String RefCount: '+GMIntToStr(StringRefCount(AStrVal)), 'REFCOUNT'); end; {$ifdef WithIntfType} procedure RGMGenericUnionValue<TStrType>.InternalAssignIntf(const AIntfVal: IUnknown); begin // Assumes Finalize() has been called before if ValueType <> uvtInterface then begin {$ifdef UseSelfManaged} IntfValue := nil; {$endif} ValueType := uvtInterface; end; IUnknown(IntfValue) := AIntfVal; end; {$endif} {$ifdef UseSelfManaged} {$if FPC_FULLVERSION < 30301} {$ERROR Self managed strings need FPC version >= 3.3.1} {$endif} class operator RGMGenericUnionValue<TStrType>.Finalize(var AUnionValue: RGMGenericUnionValue<TStrType>); begin case AUnionValue.ValueType of uvtString: if (AUnionValue.StringValue <> nil) then StrTypeCasted(AUnionValue.StringValue) := ''; {$ifdef WithIntfType} uvtInterface: if (AUnionValue.IntfValue <> nil) then IUnknown(AUnionValue.IntfValue) := nil; {$endif} end; end; class operator RGMGenericUnionValue<TStrType>.Copy(constref ASrc: RGMGenericUnionValue<TStrType>; var ADst: RGMGenericUnionValue<TStrType>); begin Finalize(ADst); case ASrc.ValueType of uvtString: ADst.InternalAssignString(StrTypeCasted(ASrc.StringValue)); {$ifdef WithIntfType} uvtInterface: ADst.InternalAssignIntf(IUnknown(ASrc.IntfValue)); {$endif} else System.Move(Asrc, ADst, SizeOf(ADst)); end; end; class operator RGMGenericUnionValue<TStrType>.AddRef(var ADst: RGMGenericUnionValue<TStrType>); // // Desperately missing something like the following here: function TStringHelper.AddRef: Integer; // type PStrRec = ^TStrRec; // <- These types are the same for unicode strings and ansi strings TStrRec = Record CodePage : TSystemCodePage; ElementSize : Word; {$if not defined(VER3_2)} {$ifdef CPU64} Ref : Longint; {$else} Ref : SizeInt; {$endif} {$else} {$ifdef CPU64} { align fields } Dummy : DWord; {$endif CPU64} Ref : SizeInt; {$endif} Len : SizeInt; end; const UnicodeFirstOff = SizeOf(TStrRec); begin case ADst.ValueType of uvtString: if ADst.StringValue <> nil then InterlockedIncrement(PStrRec(ADst.StringValue - UnicodeFirstOff)^.Ref); // <- This hack is so bad .. // StrTypeCasted(ADst.StringValue).AddRef; <- this would be so much better ... {$ifdef WithIntfType} uvtInterface: if (ADst.IntfValue <> nil) then IUnknown(ADst.IntfValue)._AddRef; {$endif} end; end; {$endif} function RGMGenericUnionValue<TStrType>.IsNull: Boolean; begin Result := ValueType = uvtNull; end; function RGMGenericUnionValue<TStrType>.IsUnassigned: Boolean; begin Result := ValueType = uvtUnassigned; end; function RGMGenericUnionValue<TStrType>.IsNullOrUnassigned: Boolean; begin Result := ValueType in [uvtUnassigned, uvtNull]; end; function RGMGenericUnionValue<TStrType>.ValueTypeName: TGMSTring; begin Result := GMUnionValueTypeName(ValueType); end; {$IFDEF FPC}{$push}{$WARN 5059 off : Function result variable does not seem to be initialized}{$ENDIF} class operator RGMGenericUnionValue<TStrType>.Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): Boolean; begin case AUnionValue.ValueType of //uvtUnassigned, uvtNull, uvtBoolean: Result := AUnionValue.BoolValue; uvtString: Result := GMStrToBool(StrTypeCasted(AUnionValue.StringValue)); uvtInt16: Result := AUnionValue.Int16Value <> 0; uvtInt32: Result := AUnionValue.Int32Value <> 0; uvtInt64: Result := AUnionValue.Int64Value <> 0; uvtDouble: Result := AUnionValue.DoubleValue <> 0.0; uvtDateTime: Result := AUnionValue.DateTimeValue <> 0.0; uvtPointer: Result := AUnionValue.PointerValue <> nil; // else raise XGMUnionValueConvertError.ObjError(GMFormat(srValueConvertToErrFmt, [AUnionValue.ValueTypeName, 'Boolean']), nil, 'RGMGenericUnionValue<TStrType>.Implicit'); else RaiseExceptionFmt(GMFormat(srValueConvertToErrFmt, [AUnionValue.ValueTypeName, 'Boolean']), nil, 'RGMGenericUnionValue<TStrType>.Implicit'); end; end; {$define InsertUnionIntCase:=//jvkUnassigned, jvkNull uvtBoolean: Result := cBoolInt[AUnionValue.BoolValue]; uvtString: Result := GMStrToInt(StrTypeCasted(AUnionValue.StringValue)); uvtInt16: Result := AUnionValue.Int16Value; uvtInt32: Result := AUnionValue.Int32Value; uvtInt64: Result := AUnionValue.Int64Value; uvtDouble: Result := Round(AUnionValue.DoubleValue); uvtDateTime: Result := Round(AUnionValue.DateTimeValue); // else raise XGMUnionValueConvertError.ObjError(GMFormat(srValueConvertToErrFmt, [AUnionValue.ValueTypeName, cResultTypeName]), nil, 'RGMGenericUnionValue<TStrType>.Implicit'); else RaiseExceptionFmt(GMFormat(srValueConvertToErrFmt, [AUnionValue.ValueTypeName, cResultTypeName]), nil, 'RGMGenericUnionValue<TStrType>.Implicit'); end;} class operator RGMGenericUnionValue<TStrType>.Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): Byte; const cResultTypeName = 'Byte'; begin case AUnionValue.ValueType of InsertUnionIntCase end; class operator RGMGenericUnionValue<TStrType>.Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): SmallInt; const cResultTypeName = 'SmallInt'; begin case AUnionValue.ValueType of InsertUnionIntCase end; class operator RGMGenericUnionValue<TStrType>.Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): Word; const cResultTypeName = 'Word'; begin case AUnionValue.ValueType of InsertUnionIntCase end; class operator RGMGenericUnionValue<TStrType>.Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): LongInt; const cResultTypeName = 'LongInt'; begin case AUnionValue.ValueType of {$IFDEF CPU32} uvtPointer: Result := LongInt(AUnionValue.PointerValue); {$ENDIF} InsertUnionIntCase end; class operator RGMGenericUnionValue<TStrType>.Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): LongWord; const cResultTypeName = 'LongWord'; begin case AUnionValue.ValueType of {$IFDEF CPU32} uvtPointer: Result := LongWord(AUnionValue.PointerValue); {$ENDIF} InsertUnionIntCase end; class operator RGMGenericUnionValue<TStrType>.Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): Int64; const cResultTypeName = 'Int64'; begin case AUnionValue.ValueType of {$IFDEF CPU64} uvtPointer: Result := Int64(AUnionValue.PointerValue); {$ELSE} uvtPointer: Result := PtrUInt(AUnionValue.PointerValue); {$ENDIF} InsertUnionIntCase end; class operator RGMGenericUnionValue<TStrType>.Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): QWord; const cResultTypeName = 'QWord'; begin case AUnionValue.ValueType of {$IFDEF CPU64} uvtPointer: Result := QWord(AUnionValue.PointerValue); {$ELSE} uvtPointer: Result := PtrUInt(AUnionValue.PointerValue); {$ENDIF} InsertUnionIntCase end; class operator RGMGenericUnionValue<TStrType>.Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): Pointer; begin case AUnionValue.ValueType of //jvkUnassigned, jvkNull //uvtBoolean: Result := cBoolInt[AUnionValue.BoolValue]; uvtString: Result := Pointer(AUnionValue.StringValue); //uvtInt16: Result := AUnionValue.Int16Value; {$IFDEF CPU64} uvtInt32: Result := Pointer(Int64(AUnionValue.Int32Value)); uvtInt64: Result := Pointer(AUnionValue.Int64Value); {$ELSE} uvtInt32: Result := Pointer(AUnionValue.Int32Value); uvtInt64: Result := Pointer(PtrUInt(AUnionValue.Int64Value)); {$ENDIF} //uvtDouble: Result := AUnionValue.DoubleValue; //uvtDateTime: Result := AUnionValue.DateTimeValue; uvtPointer: Result := AUnionValue.PointerValue; uvtInterface: Result := AUnionValue.IntfValue; // else raise XGMUnionValueConvertError.ObjError(GMFormat(srValueConvertToErrFmt, [AUnionValue.ValueTypeName, 'Pointer']), nil, 'RGMGenericUnionValue<TStrType>.Implicit'); else RaiseExceptionFmt(GMFormat(srValueConvertToErrFmt, [AUnionValue.ValueTypeName, 'Pointer']), nil, 'RGMGenericUnionValue<TStrType>.Implicit'); end; end; class operator RGMGenericUnionValue<TStrType>.Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): Single; begin case AUnionValue.ValueType of //jvkUnassigned, jvkNull uvtBoolean: Result := cBoolInt[AUnionValue.BoolValue]; uvtString: Result := GMStrToSingle(StrTypeCasted(AUnionValue.StringValue)); uvtInt16: Result := AUnionValue.Int16Value; uvtInt32: Result := AUnionValue.Int32Value; uvtInt64: Result := AUnionValue.Int64Value; uvtDouble: Result := AUnionValue.DoubleValue; uvtDateTime: Result := AUnionValue.DateTimeValue; uvtPointer: Result := PtrUInt(AUnionValue.PointerValue); // else raise XGMUnionValueConvertError.ObjError(GMFormat(srValueConvertToErrFmt, [AUnionValue.ValueTypeName, 'Single']), nil, 'RGMGenericUnionValue<TStrType>.Implicit'); else RaiseExceptionFmt(GMFormat(srValueConvertToErrFmt, [AUnionValue.ValueTypeName, 'Single']), nil, 'RGMGenericUnionValue<TStrType>.Implicit'); end; end; class operator RGMGenericUnionValue<TStrType>.Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): Double; begin case AUnionValue.ValueType of //jvkUnassigned, jvkNull uvtBoolean: Result := cBoolInt[AUnionValue.BoolValue]; uvtString: Result := GMStrToDouble(StrTypeCasted(AUnionValue.StringValue)); uvtInt16: Result := AUnionValue.Int16Value; uvtInt32: Result := AUnionValue.Int32Value; uvtInt64: Result := AUnionValue.Int64Value; uvtDouble: Result := AUnionValue.DoubleValue; uvtDateTime: Result := AUnionValue.DateTimeValue; uvtPointer: Result := PtrUInt(AUnionValue.PointerValue); // else raise XGMUnionValueConvertError.ObjError(GMFormat(srValueConvertToErrFmt, [AUnionValue.ValueTypeName, 'Double']), nil, 'RGMGenericUnionValue<TStrType>.Implicit'); else RaiseExceptionFmt(GMFormat(srValueConvertToErrFmt, [AUnionValue.ValueTypeName, 'Double']), nil, 'RGMGenericUnionValue<TStrType>.Implicit'); end; end; class operator RGMGenericUnionValue<TStrType>.Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): TDateTime; begin case AUnionValue.ValueType of //jvkUnassigned, jvkNull uvtString: Result := GMFixedDecodeDateTime(StrTypeCasted(AUnionValue.StringValue)); // GMStrToDouble(StrTypeCasted(AUnionValue.StringValue)); uvtInt16: Result := AUnionValue.Int16Value; uvtInt32: Result := AUnionValue.Int32Value; uvtInt64: Result := AUnionValue.Int64Value; uvtDouble: Result := AUnionValue.DoubleValue; uvtDateTime: Result := AUnionValue.DateTimeValue; // else raise XGMUnionValueConvertError.ObjError(GMFormat(srValueConvertToErrFmt, [AUnionValue.ValueTypeName, 'TDateTime']), nil, 'RGMGenericUnionValue<TStrType>.Implicit'); else RaiseExceptionFmt(GMFormat(srValueConvertToErrFmt, [AUnionValue.ValueTypeName, 'TDateTime']), nil, 'RGMGenericUnionValue<TStrType>.Implicit'); end; end; {$IFDEF FPC}{$pop}{$ENDIF} {$define InsertStringResultCommonPart:= case AUnionValue.ValueType of //jvkUnassigned, jvkNull uvtBoolean: Result := cBoolStr[AUnionValue.BoolValue]; uvtString: Result := StrTypeCasted(AUnionValue.StringValue); uvtInt16: Result := GMIntToStr(AUnionValue.Int16Value); uvtInt32: Result := GMIntToStr(AUnionValue.Int32Value); uvtInt64: Result := GMIntToStr(AUnionValue.Int64Value); uvtDouble: Result := GMDoubleToStr(AUnionValue.DoubleValue); uvtDateTime: Result := GMFixedEncodeDateTime(AUnionValue.DateTimeValue); // GMDateTimeToStr(AUnionValue.DateTimeValue); uvtPointer: Result := GMIntToHexStr(PtrUInt(AUnionValue.PointerValue)); {$ifdef WithIntfType} uvtInterface: Result := GMIntToHexStr(PtrUInt(AUnionValue.IntfValue)); {$endif} // else raise XGMUnionValueConvertError.ObjError(GMFormat(srValueConvertToErrFmt, [AUnionValue.ValueTypeName, cResultTypeName]), nil, 'RGMGenericUnionValue<TStrType>.Implicit'); else RaiseExceptionFmt(GMFormat(srValueConvertToErrFmt, [AUnionValue.ValueTypeName, cResultTypeName]), nil, 'RGMGenericUnionValue<TStrType>.Implicit'); end;} class operator RGMGenericUnionValue<TStrType>.Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): UnicodeString; const cResultTypeName = 'UnicodeString'; begin InsertStringResultCommonPart end; class operator RGMGenericUnionValue<TStrType>.Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): WideString; const cResultTypeName = 'WideString'; begin InsertStringResultCommonPart end; class operator RGMGenericUnionValue<TStrType>.Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): AnsiString; const cResultTypeName = 'AnsiString'; begin InsertStringResultCommonPart end; class operator RGMGenericUnionValue<TStrType>.Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): Utf8String; const cResultTypeName = 'Utf8String'; begin InsertStringResultCommonPart end; class operator RGMGenericUnionValue<TStrType>.Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): Variant; begin case AUnionValue.ValueType of //uvtUnassigned: Result := Unassigned; uvtNull: Result := Variants.Null; uvtString: Result := AUnionValue.AsString; uvtBoolean: Result := AUnionValue.BoolValue; uvtInt16: Result := AUnionValue.Int16Value; uvtInt32: Result := AUnionValue.Int32Value; uvtInt64: Result := AUnionValue.Int64Value; uvtDouble: Result := AUnionValue.DoubleValue; uvtDateTime: Result := AUnionValue.DateTimeValue; uvtPointer: Result := AUnionValue.PointerValue; else Result := Variants.Unassigned; end; end; class operator RGMGenericUnionValue<TStrType>.Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): OleVariant; begin case AUnionValue.ValueType of //uvtUnassigned: Result := Unassigned; uvtNull: Result := Variants.Null; uvtString: Result := AUnionValue.AsString; uvtBoolean: Result := AUnionValue.BoolValue; uvtInt16: Result := AUnionValue.Int16Value; uvtInt32: Result := AUnionValue.Int32Value; uvtInt64: Result := AUnionValue.Int64Value; uvtDouble: Result := AUnionValue.DoubleValue; uvtDateTime: Result := AUnionValue.DateTimeValue; //uvtPointer: Result := AValue.PointerValue; else Result := Variants.Unassigned; end; end; {$ifdef WithIntfType} class operator RGMGenericUnionValue<TStrType>.Implicit(const AUnionValue: RGMGenericUnionValue<TStrType>): IUnknown; begin case AUnionValue.ValueType of //uvtUnassigned: Result := Unassigned; //{$ifdef CPU64} //uvtInt64: Result := Pointer(AUnionValue.Int64Value); //{$else} //uvtInt32: Result := Pointer(AUnionValue.Int32Value); //{$endif} uvtPointer: Result := AUnionValue.PointerValue; {$ifdef WithIntfType} uvtInterface: Result := IUnknown(AUnionValue.IntfValue); {$endif} else RaiseExceptionFmt(GMFormat(srValueConvertToErrFmt, [AUnionValue.ValueTypeName, 'IUnknown']), nil, 'RGMGenericUnionValue<TStrType>.Implicit'); end; end; {$endif} class operator RGMGenericUnionValue<TStrType>.Implicit(AValue: EGMUnionValueType): RGMGenericUnionValue<TStrType>; begin Finalize(Result); case AValue of uvtUnassigned, uvtNull: Result.ValueType := AValue; // else raise XGMUnionValueConvertError.ObjError(GMFormat(srValueConvertFromErrFmt, [GMUnionValueTypeName(AValue)]), nil, 'RGMGenericUnionValue<TStrType>.Implicit'); else RaiseExceptionFmt(GMFormat(srValueConvertFromErrFmt, [GMUnionValueTypeName(AValue)]), nil, 'RGMGenericUnionValue<TStrType>.Implicit'); end; end; class operator RGMGenericUnionValue<TStrType>.Implicit(AValue: Boolean): RGMGenericUnionValue<TStrType>; begin Finalize(Result); Result.ValueType := uvtBoolean; Result.BoolValue := AValue; end; class operator RGMGenericUnionValue<TStrType>.Implicit(AValue: SmallInt): RGMGenericUnionValue<TStrType>; begin Finalize(Result); Result.Int16Value := AValue; Result.ValueType := uvtInt16; end; class operator RGMGenericUnionValue<TStrType>.Implicit(AValue: LongInt): RGMGenericUnionValue<TStrType>; begin Finalize(Result); Result.ValueType := uvtInt32; Result.Int32Value := AValue; end; class operator RGMGenericUnionValue<TStrType>.Implicit(AValue: Int64): RGMGenericUnionValue<TStrType>; begin Finalize(Result); Result.Int64Value := AValue; Result.ValueType := uvtInt64; end; class operator RGMGenericUnionValue<TStrType>.Implicit(AValue: Double): RGMGenericUnionValue<TStrType>; begin Finalize(Result); Result.ValueType := uvtDouble; Result.DoubleValue := AValue; end; class operator RGMGenericUnionValue<TStrType>.Implicit(AValue: TDateTime): RGMGenericUnionValue<TStrType>; begin Finalize(Result); Result.DateTimeValue := AValue; Result.ValueType := uvtDateTime; end; class operator RGMGenericUnionValue<TStrType>.Implicit(AValue: Pointer): RGMGenericUnionValue<TStrType>; begin Finalize(Result); Result.ValueType := uvtPointer; Result.PointerValue := AValue; end; class operator RGMGenericUnionValue<TStrType>.Implicit(AValue: UnicodeString): RGMGenericUnionValue<TStrType>; begin Finalize(Result); Result.InternalAssignString(AValue); end; class operator RGMGenericUnionValue<TStrType>.Implicit(AValue: WideString): RGMGenericUnionValue<TStrType>; begin Finalize(Result); Result.InternalAssignString(AValue); end; class operator RGMGenericUnionValue<TStrType>.Implicit(AValue: AnsiString): RGMGenericUnionValue<TStrType>; begin Finalize(Result); Result.InternalAssignString(AValue); end; class operator RGMGenericUnionValue<TStrType>.Implicit(AValue: Utf8String): RGMGenericUnionValue<TStrType>; begin Finalize(Result); Result.InternalAssignString(AValue); end; {$define InsertAssignFromVariantCommonPart:= //Result := Default(RGMGenericUnionValue<TStrType>); // <- Result may be a re-used instance, assignmet will finalize it before assign //Finalize(Result); case VarType(AValue) of //varEmpty: Result := uvtUnassigned; <- handeled by else case varNull: Result := uvtNull; varBoolean: Result := Boolean(AValue); // AValue.vBoolean; varSmallint: Result := SmallInt(AValue); // AValue.vSmallint; varWord: Result := Word(AValue); // AValue.vWord; varInteger: Result := LongInt(AValue); // AValue.vInteger; varLongword: Result := Longword(AValue); // AValue.vLongword; varInt64: Result := Int64(AValue); // AValue.vInt64; varQWord: Result := QWord(AValue); // AValue.vQWord; varSingle: Result := Single(AValue); // AValue.vSingle; varDouble: Result := Double(AValue); // AValue.vDouble; varDate: Result := TDateTime(AValue); // AValue.vDate; varOleStr, varString: Result := GMVarToStr(AValue); {$ifdef WithIntfType} varUnknown, varDispatch: Result := IUnknown(AValue); // AValue.vUnknown; {$else} varUnknown, varDispatch: Result := Pointer(IUnknown(AValue)); // AValue.vUnknown; {$endif} varError: Result := AValue.vError; else Result := uvtUnassigned; end;} class operator RGMGenericUnionValue<TStrType>.Implicit(AValue: Variant): RGMGenericUnionValue<TStrType>; begin InsertAssignFromVariantCommonPart end; class operator RGMGenericUnionValue<TStrType>.Implicit(AValue: OleVariant): RGMGenericUnionValue<TStrType>; begin InsertAssignFromVariantCommonPart end; {$ifdef WithIntfType} class operator RGMGenericUnionValue<TStrType>.Implicit(AValue: IUnknown): RGMGenericUnionValue<TStrType>; begin Finalize(Result); Result.ValueType := uvtInterface; IUnknown(Result.IntfValue) := AValue; end; {$endif} class operator RGMGenericUnionValue<TStrType>.Equal(const AUnionValue: RGMGenericUnionValue<TStrType>; AValue: Int64): Boolean; begin Result := AUnionValue.AsInt64 = AValue; end; class operator RGMGenericUnionValue<TStrType>.Equal(const AUnionValue: RGMGenericUnionValue<TStrType>; AValue: LongInt): Boolean; begin Result := AUnionValue.AsInt32 = AValue; end; class operator RGMGenericUnionValue<TStrType>.Equal(const AUnionValue: RGMGenericUnionValue<TStrType>; AValue: Pointer): Boolean; begin Result := AUnionValue.AsPointer = AValue; end; {$ifdef WithIntfType} class operator RGMGenericUnionValue<TStrType>.Equal(const AUnionValue: RGMGenericUnionValue<TStrType>; AValue: IUnknown): Boolean; begin Result := AUnionValue.AsInterface = AValue; end; {$endif} class operator RGMGenericUnionValue<TStrType>.Equal(const AUnionValue: RGMGenericUnionValue<TStrType>; AValue: Double): Boolean; begin Result := AUnionValue.AsDouble = AValue; end; //class operator RGMGenericUnionValue<TStrType>.Equal(const AUnionValue: RGMGenericUnionValue<TStrType>; AValue: TDateTime): Boolean; //begin // Result := AUnionValue.AsDateTime = AValue; //end; class operator RGMGenericUnionValue<TStrType>.Equal(const AUnionValue: RGMGenericUnionValue<TStrType>; AValue: UnicodeString): Boolean; begin Result := AUnionValue.AsString = AValue; end; class operator RGMGenericUnionValue<TStrType>.Equal(const AUnionValue: RGMGenericUnionValue<TStrType>; AValue: WideString): Boolean; begin Result := AUnionValue.AsString = AValue; end; class operator RGMGenericUnionValue<TStrType>.Equal(const AUnionValue: RGMGenericUnionValue<TStrType>; AValue: AnsiString): Boolean; begin Result := AUnionValue.AsString = AValue; end; class operator RGMGenericUnionValue<TStrType>.Equal(const AUnionValue: RGMGenericUnionValue<TStrType>; AValue: Utf8String): Boolean; begin Result := AUnionValue.AsString = AValue; end; class operator RGMGenericUnionValue<TStrType>.Equal(const AValue1, AValue2: RGMGenericUnionValue<TStrType>): Boolean; begin case AValue1.ValueType of uvtUnassigned: Result := AValue2.ValueType = uvtUnassigned; uvtNull: Result := AValue2.ValueType = uvtNull; uvtString: case AValue2.ValueType of uvtString: Result := GMSameText(AValue1.AsString, AValue2.AsString); uvtBoolean, uvtInt16, uvtInt32, uvtInt64, uvtDouble, uvtDateTime: Result := GMSameText(AValue1.AsString, AValue2.AsString); else Result := False; end; uvtBoolean: case AValue2.ValueType of uvtBoolean: Result := AValue1.BoolValue = AValue2.BoolValue; uvtInt16, uvtInt32, uvtInt64: Result := AValue1.BoolValue = (AValue2.AsInt64 <> 0); uvtdouble: Result := AValue1.BoolValue = (AVAlue2.DoubleValue <> 0); uvtString: Result := AValue1.BoolValue = GMStrToBool(StrTypeCasted(AValue2.StringValue)); else Result := False; end; uvtInt16, uvtInt32, uvtInt64: case AValue2.ValueType of //uvtString: Result := AValue1.AsInt64 = //uvtBoolean, //uvtString: Result uvtInt16, uvtInt32, uvtInt64: Result := AValue1.AsInt64 = AValue2.AsInt64; uvtDouble, uvtDateTime: Result := AValue1.AsInt64 = AValue2.DoubleValue; else Result := False; end; uvtDouble, uvtDateTime: case AValue2.ValueType of //uvtString, uvtBoolean, //uvtString, uvtInt16, uvtInt32, uvtInt64: Result := AValue1.DoubleValue = AValue2.AsInt64; uvtDouble, uvtDateTime: Result := AValue1.DoubleValue = AValue2.DoubleValue; else Result := False; end; uvtPointer: case AValue2.ValueType of {$IFDEF CPU32} uvtInt32: Result := PtrUInt(AValue1.PointerValue) = PtrUInt(AValue2.AsInt32); {$ENDIF} {$IFDEF CPU64} uvtInt64: Result := PtrUInt(AValue1.PointerValue) = PtrUInt(AValue2.AsInt64); {$ENDIF} uvtPointer: Result := AValue1.PointerValue = AValue2.PointerValue; else Result := False; end; {$ifdef WithIntfType} uvtInterface: case AValue2.ValueType of uvtPointer: Result := AValue1.IntfValue = AValue2.PointerValue; uvtInterface: Result := AValue1.IntfValue = AValue2.IntfValue; else Result := False; end {$endif} else Result := False; end; end; class operator RGMGenericUnionValue<TStrType>.NotEqual(const AValue1, AValue2: RGMGenericUnionValue<TStrType>): Boolean; begin Result := not (AValue1 = AValue2); end; class operator RGMGenericUnionValue<TStrType>.Add(const AValue1, AValue2: RGMGenericUnionValue<TStrType>): RGMGenericUnionValue<TStrType>; begin case AValue1.ValueType of uvtInt16, uvtInt32, uvtInt64: case AValue2.ValueType of uvtInt16, uvtInt32, uvtInt64: Result := AValue1.AsInt64 + AValue2.AsInt64; else Result := AValue1.AsDouble + AValue2.AsDouble; end; else Result := AValue1.AsDouble + AValue2.AsDouble; end; end; class operator RGMGenericUnionValue<TStrType>.Multiply(const AValue1, AValue2: RGMGenericUnionValue<TStrType>): RGMGenericUnionValue<TStrType>; begin case AValue1.ValueType of uvtInt16, uvtInt32, uvtInt64: case AValue2.ValueType of uvtInt16, uvtInt32, uvtInt64: Result := AValue1.AsInt64 * AValue2.AsInt64; else Result := AValue1.AsDouble * AValue2.AsDouble; end; else Result := AValue1.AsDouble * AValue2.AsDouble; end; end; class operator RGMGenericUnionValue<TStrType>.Divide(const AValue1, AValue2: RGMGenericUnionValue<TStrType>): RGMGenericUnionValue<TStrType>; begin case AValue1.ValueType of uvtInt16, uvtInt32, uvtInt64: case AValue2.ValueType of uvtInt16, uvtInt32, uvtInt64: Result := AValue1.AsInt64 / AValue2.AsInt64; else Result := AValue1.AsDouble / AValue2.AsDouble; end; else Result := AValue1.AsDouble / AValue2.AsDouble; end; end; class operator RGMGenericUnionValue<TStrType>.IntDivide(const AValue1, AValue2: RGMGenericUnionValue<TStrType>): RGMGenericUnionValue<TStrType>; begin Result := AValue1.AsInt64 div AValue2.AsInt64; end; class operator RGMGenericUnionValue<TStrType>.Modulus(const AValue1, AValue2: RGMGenericUnionValue<TStrType>): RGMGenericUnionValue<TStrType>; begin Result := AValue1.AsInt64 mod AValue2.AsInt64; end; class operator RGMGenericUnionValue<TStrType>.LessThan(const AValue1, AValue2: RGMGenericUnionValue<TStrType> ): Boolean; begin case AValue1.ValueType of uvtUnassigned, uvtNull: Result := AValue2.ValueType > uvtNull; uvtString: case AValue2.ValueType of uvtString: Result := GMCompareNames(StrTypeCasted(AValue1.StringValue), StrTypeCasted(AValue2.StringValue)) = crALessThanB; uvtBoolean, uvtInt16, uvtInt32, uvtInt64, uvtDouble, uvtDateTime: Result := GMCompareNames(StrTypeCasted((AValue1.StringValue)), AValue2.AsString) = crALessThanB; else Result := False; end; uvtBoolean: case AValue2.ValueType of uvtBoolean: Result := AValue1.BoolValue < AValue2.BoolValue; uvtInt16, uvtInt32, uvtInt64: Result := AValue1.BoolValue < (AValue2.AsInt64 <> 0); uvtdouble: Result := AValue1.BoolValue < (AVAlue2.DoubleValue <> 0); uvtString: Result := AValue1.BoolValue < GMStrToBool(StrTypeCasted(AValue2.StringValue)); else Result := False; end; uvtInt16, uvtInt32, uvtInt64: case AValue2.ValueType of //uvtString: Result := AValue1.AsInt64 = //uvtBoolean, //uvtString: Result uvtInt16, uvtInt32, uvtInt64: Result := AValue1.AsInt64 < AValue2.AsInt64; uvtDouble, uvtDateTime: Result := AValue1.AsInt64 < AValue2.DoubleValue; else Result := False; end; uvtDouble, uvtDateTime: case AValue2.ValueType of //uvtString, uvtBoolean, //uvtString, uvtInt16, uvtInt32, uvtInt64: Result := AValue1.DoubleValue < AValue2.AsInt64; uvtDouble, uvtDateTime: Result := AValue1.DoubleValue < AValue2.DoubleValue; else Result := False; end; uvtPointer: case AValue2.ValueType of {$IFDEF CPU32} uvtInt32: Result := PtrUInt(AValue1.PointerValue) < PtrUInt(AValue2.AsInt32); {$ENDIF} {$IFDEF CPU64} uvtInt64: Result := PtrUInt(AValue1.PointerValue) < PtrUInt(AValue2.AsInt64); {$ENDIF} uvtPointer: Result := AValue1.PointerValue < AValue2.PointerValue; else Result := False; end; {$ifdef WithIntfType} uvtInterface: case AValue2.ValueType of uvtPointer: Result := AValue1.IntfValue < AValue2.PointerValue; uvtInterface: Result := AValue1.IntfValue < AValue2.IntfValue; else Result := False; end {$endif} else Result := False; end; end; class operator RGMGenericUnionValue<TStrType>.GreaterThan(const AValue1, AValue2: RGMGenericUnionValue<TStrType>): Boolean; begin Result := not ((AValue1 < AValue2) or (AValue1 = AValue2)); end; class operator RGMGenericUnionValue<TStrType>.LessThanOrEqual(const AValue1, AValue2: RGMGenericUnionValue<TStrType>): Boolean; begin Result := (AValue1 < AValue2) or (AValue1 = AValue2); end; class operator RGMGenericUnionValue<TStrType>.GreaterThanOrEqual(const AValue1, AValue2: RGMGenericUnionValue<TStrType>): Boolean; begin Result := not (AValue1 < AValue2); // (AValue1 > AValue2) or (AValue1 = AValue2); end; function RGMGenericUnionValue<TStrType>.AsBoolean: Boolean; begin Result := Self; end; function RGMGenericUnionValue<TStrType>.AsInt16: SmallInt; begin Result := Self; end; function RGMGenericUnionValue<TStrType>.AsInt32: LongInt; begin Result := Self; end; function RGMGenericUnionValue<TStrType>.AsInt64: Int64; begin Result := Self; end; function RGMGenericUnionValue<TStrType>.AsDouble: Double; begin Result := Self; end; function RGMGenericUnionValue<TStrType>.AsDateTime: TDateTime; begin Result := Self; end; function RGMGenericUnionValue<TStrType>.AsString: TGMString; begin Result := Self; end; function RGMGenericUnionValue<TStrType>.AsPointer: Pointer; begin Result := Self; end; {$ifdef WithIntfType} function RGMGenericUnionValue<TStrType>.AsInterface: IUnknown; begin Result := Self; end; {$endif} //function RGMGenericUnionValue<TStrType>.AsDisplayString: TGMString; //begin // case ValueType of // uvtUnassigned, uvtNull: Result := ''; // else Result := Self; // end; //end; {$define CommonAsDfltresult:= case ValueType of uvtUnassigned, uvtNull: Result := ADefaultValue; else Result := Self; end;} function RGMGenericUnionValue<TStrType>.AsBooleanDflt(const ADefaultValue: Boolean): Boolean; begin CommonAsDfltresult end; function RGMGenericUnionValue<TStrType>.AsInt16Dflt(const ADefaultValue: SmallInt): SmallInt; begin CommonAsDfltresult end; function RGMGenericUnionValue<TStrType>.AsInt32Dflt(const ADefaultValue: LongInt): LongInt; begin CommonAsDfltresult end; function RGMGenericUnionValue<TStrType>.AsInt64Dflt(const ADefaultValue: Int64): Int64; begin CommonAsDfltresult end; function RGMGenericUnionValue<TStrType>.AsDoubleDflt(const ADefaultValue: Double): Double; begin CommonAsDfltresult end; function RGMGenericUnionValue<TStrType>.AsDateTimeDflt(const ADefaultValue: TDateTime): TDateTime; begin CommonAsDfltresult end; function RGMGenericUnionValue<TStrType>.AsPointerDflt(const ADefaultValue: Pointer): Pointer; begin CommonAsDfltresult end; function RGMGenericUnionValue<TStrType>.AsStringDflt(const ADefaultValue: TGMString): TGMString; begin CommonAsDfltresult end; {$ifdef WithIntfType} function RGMGenericUnionValue<TStrType>.AsInterfaceDflt(const ADefaultValue: IUnknown): IUnknown; begin CommonAsDfltresult end; {$endif} end.