Unit SysVariant;

{$BOOLEVAL OFF}

Interface

Const
  { Variant type codes (wtypes.h) }

  varEmpty = $0000; { vt_empty        0 }
  varNull = $0001; { vt_null         1 }
  varSmallint = $0002; { vt_i2           2 }
  varInteger = $0003; { vt_i4           3 }
  varSingle = $0004; { vt_r4           4 }
  varDouble = $0005; { vt_r8           5 }
  varCurrency = $0006; { vt_cy           6 }
  varDate = $0007; { vt_date         7 }
  varOleStr = $0008; { vt_bstr         8 }
  varDispatch = $0009; { vt_dispatch     9 }
  varError = $000A; { vt_error       10 }
  varBoolean = $000B; { vt_bool        11 }
  varVariant = $000C; { vt_variant     12 }
  varUnknown = $000D; { vt_unknown     13 }
  varShortInt = $0010; { vt_i1          16 }
  varByte = $0011; { vt_ui1         17 }
  varWord = $0012; { vt_ui2         18 }
  varLongWord = $0013; { vt_ui4         19 }
  varInt64 = $0014; { vt_i8          20 }
  { if adding new items, update Variants' varLast, BaseTypeMap and OpTypeMap }

  varStrArg = $0048; { vt_clsid       72 }
  varString = $0100; { Pascal string 256 } { not OLE compatible }
  varAny = $0101; { Corba any     257 } { not OLE compatible }
  // custom types range from $110 (272) to $7FF (2047)

  varTypeMask = $0FFF;
  varArray = $2000;
  varByRef = $4000;

Type
  TVarType = Word;

Function FindVarData(Const V: Variant): PVarData;
Function VarIsOrdinal(Const V: Variant): Boolean;

Implementation

Function FindVarData(Const V: Variant): PVarData;
Begin
  Result := @TVarData(V);
  While Result.VType = varByRef or varVariant Do
    Result := PVarData(Result.VPointer);
End;

Function VarTypeIsOrdinal(Const AVarType: TVarType): Boolean;
Begin
  Result := AVarType in [varSmallint, varInteger, varBoolean, varShortInt, varByte, varWord, varLongWord, varInt64];
End;

Function VarIsOrdinal(Const V: Variant): Boolean;
Begin
  Result := VarTypeIsOrdinal(FindVarData(V)^.VType);
End;

End.
