Skip to content

TVariant

Ivan Semenkov edited this page Jan 30, 2021 · 1 revision

Table of contents

About

The class template TVariant represents a type-safe union. An instance of variant at any given time either holds a value of one of its alternative types, or in the case of error raise ETypeUndefinedException.

As with unions, if a variant holds a value of some object type T, the object representation of T is allocated directly within the object representation of the variant itself. Variant is not allowed to allocate additional (dynamic) memory.

TVariant2

uses
  utils.variant;
  
type
  generic TVariant2<T1, T2> = class
  type
    TVariantValue1 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T1>;
    TVariantValue2 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T2>;
  end;

TVariantValueResultValue is custom variant value implementation.

TVariant3

uses
  utils.variant;
  
type
  generic TVariant3<T1, T2, T3> = class
  type
    TVariantValue1 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T1>;
    TVariantValue2 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T2>;
    TVariantValue3 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T3>;
  end;

TVariantValueResultValue is custom variant value implementation.

TVariant4

uses
  utils.variant;
  
type
  generic TVariant4<T1, T2, T3, T4> = class
  type
    TVariantValue1 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T1>;
    TVariantValue2 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T2>;
    TVariantValue3 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T3>;
    TVariantValue4 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T4>;
  end;

TVariantValueResultValue is custom variant value implementation.

TVariant5

uses
  utils.variant;
  
type
  generic TVariant5<T1, T2, T3, T4, T5> = class
  type
    TVariantValue1 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T1>;
    TVariantValue2 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T2>;
    TVariantValue3 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T3>;
    TVariantValue4 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T4>;
    TVariantValue5 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T5>;
  end;

TVariantValueResultValue is custom variant value implementation.

TVariant6

uses
  utils.variant;
  
type
  generic TVariant6<T1, T2, T3, T4, T5, T6> = class
  type
    TVariantValue1 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T1>;
    TVariantValue2 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T2>;
    TVariantValue3 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T3>;
    TVariantValue4 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T4>;
    TVariantValue5 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T5>;
    TVariantValue6 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T6>;
  end;

TVariantValueResultValue is custom variant value implementation.

TVariant7

uses
  utils.variant;
  
type
  generic TVariant7<T1, T2, T3, T4, T5, T6, T7> = class
  type
    TVariantValue1 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T1>;
    TVariantValue2 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T2>;
    TVariantValue3 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T3>;
    TVariantValue4 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T4>;
    TVariantValue5 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T5>;
    TVariantValue6 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T6>;
    TVariantValue7 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T7>;
  end;

TVariantValueResultValue is custom variant value implementation.

TVariant8

uses
  utils.variant;
  
type
  generic TVariant8<T1, T2, T3, T4, T5, T6, T7, T8> = class
  type
    TVariantValue1 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T1>;
    TVariantValue2 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T2>;
    TVariantValue3 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T3>;
    TVariantValue4 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T4>;
    TVariantValue5 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T5>;
    TVariantValue6 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T6>;
    TVariantValue7 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T7>;
    TVariantValue8 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T8>;
  end;

TVariantValueResultValue is custom variant value implementation.

TVariant9

uses
  utils.variant;
  
type
  generic TVariant9<T1, T2, T3, T4, T5, T6, T7, T8, T9> = class
  type
    TVariantValue1 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T1>;
    TVariantValue2 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T2>;
    TVariantValue3 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T3>;
    TVariantValue4 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T4>;
    TVariantValue5 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T5>;
    TVariantValue6 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T6>;
    TVariantValue7 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T7>;
    TVariantValue8 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T8>;
    TVariantValue9 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T9>;
  end;

TVariantValueResultValue is custom variant value implementation.

TVariant10

uses
  utils.variant;
  
type
  generic TVariant9<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> = class
  type
    TVariantValue1 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T1>;
    TVariantValue2 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T2>;
    TVariantValue3 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T3>;
    TVariantValue4 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T4>;
    TVariantValue5 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T5>;
    TVariantValue6 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T6>;
    TVariantValue7 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T7>;
    TVariantValue8 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T8>;
    TVariantValue9 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T9>;
    TVariantValue10 = {$IFDEF FPC}specialize{$ENDIF} TVariantResultValue<T10>;
  end;

TVariantValueResultValue is custom variant value implementation.

TValueType

It is enum which represent variant stored value types.

TValueType = (
    VALUE_TYPE1,
    VALUE_TYPE2,
    VALUE_TYPE3,
    VALUE_TYPE4,
    VALUE_TYPE5,
    VALUE_TYPE6,
    VALUE_TYPE7,
    VALUE_TYPE8,
    VALUE_TYPE9,
    VALUE_TYPE10
  );

TVariantResultValue

It is a wrapper for variant custom value.

uses
  utils.variant;
  
type
  generic TVariantResultValue<T> = class

Value

Return concreate variant item value.

function Value : T;

ETypeUndefinedException

Raised when trying to get a value that does not exist.

ETypeUndefinedException = class(Exception);

Create

A new variant can be created by call its constructor.

TVariant2

constructor Create;
Example
uses
  utils.variant;
  
type
  TValue1Type = type Integer;
  TValue2Type = type String;
  TVariantValue = {$IFDEF FPC}specialize{$ENDIF} TVariant2<TValue1Type, TValue2Type>;
  
var
  variant : TVariantValue;
  
begin
  variant := TVariantValue.Create;
    
  FreeAndNil(variant);
end;

TVariant3

constructor Create;
Example
uses
  utils.variant;
  
type
  TValue1Type = type Integer;
  TValue2Type = type String;
  TValue3Type = type Byte;
  TVariantValue = {$IFDEF FPC}specialize{$ENDIF} TVariant3<TValue1Type, TValue2Type,
    TValue3Type>;
  
var
  variant : TVariantValue;
  
begin
  variant := TVariantValue.Create;
    
  FreeAndNil(variant);
end;

TVariant4

constructor Create;
Example
uses
  utils.variant;
  
type
  TValue1Type = type Integer;
  TValue2Type = type String;
  TValue3Type = type Byte;
  TValue4Type = type Integer;
  TVariantValue = {$IFDEF FPC}specialize{$ENDIF} TVariant4<TValue1Type, TValue2Type,
    TValue3Type, TValue4Type>;
  
var
  variant : TVariantValue;
  
begin
  variant := TVariantValue.Create;
    
  FreeAndNil(variant);
end;

TVariant5

constructor Create;
Example
uses
  utils.variant;
  
type
  TValue1Type = type Integer;
  TValue2Type = type String;
  TValue3Type = type Byte;
  TValue4Type = type Integer;
  TValue5Type = type Pointer;
  TVariantValue = {$IFDEF FPC}specialize{$ENDIF} TVariant5<TValue1Type, TValue2Type,
    TValue3Type, TValue4Type, TValue5Type>;
  
var
  variant : TVariantValue;
  
begin
  variant := TVariantValue.Create;
    
  FreeAndNil(variant);
end;

TVariant6

constructor Create;
Example
uses
  utils.variant;
  
type
  TValue1Type = type Integer;
  TValue2Type = type String;
  TValue3Type = type Byte;
  TValue4Type = type Integer;
  TValue5Type = type Pointer;
  TValue6Type = type String;
  TVariantValue = {$IFDEF FPC}specialize{$ENDIF} TVariant6<TValue1Type, TValue2Type,
    TValue3Type, TValue4Type, TValue5Type, TValue6Type>;
  
var
  variant : TVariantValue;
  
begin
  variant := TVariantValue.Create;
    
  FreeAndNil(variant);
end;

TVariant7

constructor Create;
Example
uses
  utils.variant;
  
type
  TValue1Type = type Integer;
  TValue2Type = type String;
  TValue3Type = type Byte;
  TValue4Type = type Integer;
  TValue5Type = type Pointer;
  TValue6Type = type String;
  TValue7Type = type String;
  TVariantValue = {$IFDEF FPC}specialize{$ENDIF} TVariant7<TValue1Type, TValue2Type,
    TValue3Type, TValue4Type, TValue5Type, TValue6Type, TValue7Type>;
  
var
  variant : TVariantValue;
  
begin
  variant := TVariantValue.Create;
    
  FreeAndNil(variant);
end;

TVariant8

constructor Create;
Example
uses
  utils.variant;
  
type
  TValue1Type = type Integer;
  TValue2Type = type String;
  TValue3Type = type Byte;
  TValue4Type = type Integer;
  TValue5Type = type Pointer;
  TValue6Type = type String;
  TValue7Type = type String;
  TValue8Type = type Pointer;
  TVariantValue = {$IFDEF FPC}specialize{$ENDIF} TVariant8<TValue1Type, TValue2Type,
    TValue3Type, TValue4Type, TValue5Type, TValue6Type, TValue7Type, TValue8Type>;
  
var
  variant : TVariantValue;
  
begin
  variant := TVariantValue.Create;
    
  FreeAndNil(variant);
end;

TVariant9

constructor Create;
Example
uses
  utils.variant;
  
type
  TValue1Type = type Integer;
  TValue2Type = type String;
  TValue3Type = type Byte;
  TValue4Type = type Integer;
  TValue5Type = type Pointer;
  TValue6Type = type String;
  TValue7Type = type String;
  TValue8Type = type Pointer;
  TValue9Type = type Integer;
  TVariantValue = {$IFDEF FPC}specialize{$ENDIF} TVariant9<TValue1Type, TValue2Type,
    TValue3Type, TValue4Type, TValue5Type, TValue6Type, TValue7Type, TValue8Type,
    TValue9Type>;
  
var
  variant : TVariantValue;
  
begin
  variant := TVariantValue.Create;
    
  FreeAndNil(variant);
end;

TVariant10

constructor Create;
Example
uses
  utils.variant;
  
type
  TValue1Type = type Integer;
  TValue2Type = type String;
  TValue3Type = type Byte;
  TValue4Type = type Integer;
  TValue5Type = type Pointer;
  TValue6Type = type String;
  TValue7Type = type String;
  TValue8Type = type Pointer;
  TValue9Type = type Integer;
  TValue10Type = type Integer;
  TVariantValue = {$IFDEF FPC}specialize{$ENDIF} TVariant10<TValue1Type, TValue2Type,
    TValue3Type, TValue4Type, TValue5Type, TValue6Type, TValue7Type, TValue8Type,
    TValue9Type, TValue10Type>;
  
var
  variant : TVariantValue;
  
begin
  variant := TVariantValue.Create;
    
  FreeAndNil(variant);
end;

GetType

Return variant value type.

function GetType : TValueType;

Result value present as a TValueType.

Example
uses
  utils.variant;
  
type
  TValue1Type = type Integer;
  TValue2Type = type String;
  TVariantValue = {$IFDEF FPC}specialize{$ENDIF} TVariant2<TValue1Type, TValue2Type>;
  
var
  variant : TVariantValue;
  
begin
  variant := TVariantValue.Create;
  case variant.GetType of
    VALUE_TYPE1 : ;
    VALUE_TYPE2 : ;
  end;
    
  FreeAndNil(variant);
end;

GetValue

Return variant value.

function GetValue : TVariantValue;

Result value present as a TVariantResultValue type.

Example
uses
  utils.variant;
  
type
  TValue1Type = type Integer;
  TValue2Type = type String;
  TVariantValue = {$IFDEF FPC}specialize{$ENDIF} TVariant2<TValue1Type, TValue2Type>;
  
var
  variant : TVariantValue;
  
begin
  variant := TVariantValue.Create;
  case variant.GetType of
    VALUE_TYPE1 : writeln(TVariantValue.TVariantValue1(variant.GetValue).Value);
    VALUE_TYPE2 : writeln(TVariantValue.TVariantValue2(variant.GetValue).Value);
  end;
    
  FreeAndNil(variant);
end;

SetValue

Set variant value.

procedure SetValue (AValue : T1);
procedure SetValue (AValue : T2);
procedure SetValue (AValue : T3);
procedure SetValue (AValue : T4);
procedure SetValue (AValue : T5);
procedure SetValue (AValue : T6);
procedure SetValue (AValue : T7);
procedure SetValue (AValue : T8);
procedure SetValue (AValue : T9);
procedure SetValue (AValue : T10);
Example
uses
  utils.variant;
  
type
  TValue1Type = type Integer;
  TValue2Type = type String;
  TVariantValue = {$IFDEF FPC}specialize{$ENDIF} TVariant2<TValue1Type, TValue2Type>;
  
var
  variant : TVariantValue;
  
begin
  variant := TVariantValue.Create;
  variant.SetValue(TValue1Type(12));
  variant.SetValue(TValue2Type('some value'));
  
  FreeAndNil(variant);
end;