Writing Utilities to Work with a Custom Variant Type
Go Up to Using the RTL Index
Once you have created a TCustomVariantType descendant to implement your custom variant type, it is possible to use the new Variant type in applications. However, without a few utilities, this is not as easy as it should be.
It is a good idea to create a method that creates an instance of your custom variant type from an appropriate value or set of values. This function or set of functions fills out the structure you defined to store your custom variant's data. For example, the following function could be used to create a complex-valued variant:
function VarComplexCreate(const AReal, AImaginary: Double): Variant; begin VarClear(Result); TComplexVarData(Result).VType := ComplexVariantType.VarType; TComplexVarData(ADest).VComplex := TComplexData.Create(ARead, AImaginary); end;
This function does not actually exist in the VarCmplx unit, but is a synthesis of methods that do exist, provided to simplify the example. Note that the returned variant is cast to the record that was defined to map onto the
TVarData structure (
TComplexVarData), and then filled out.
Another useful utility to create is one that returns the variant type code for your new Variant type. This type code is not a constant. It is automatically generated when you instantiate your
TCustomVariantType descendant. It is therefore useful to provide a way to easily determine the type code for your custom variant type. The following function from the VarCmplx unit illustrates how to write one, by simply returning the
VarType property of the
function VarComplex: TVarType; begin Result := ComplexVariantType.VarType; end;
Two other standard utilities provided for most custom variants check whether a given variant is of the custom type and cast an arbitrary variant to the new custom type. Here is the implementation of those utilities from the VarCmplx unit:
function VarIsComplex(const AValue: Variant): Boolean; begin Result := (TVarData(AValue).VType and varTypeMask) = VarComplex; end; function VarAsComplex(const AValue: Variant): Variant; begin if not VarIsComplex(AValue) then VarCast(Result, AValue, VarComplex) else Result := AValue; end;
Note that these use standard features of all variants: the
VType member of the
TVarData record and the
VarCast function, which works because of the methods implemented in the TCustomVariantType descendant for casting data.
In addition to the standard utilities mentioned above, you can write any number of utilities specific to your new custom variant type. For example, the VarCmplx unit defines a large number of functions that implement mathematical operations on complex-valued variants.