{
    This file is part of the Free Pascal run time library.
    Copyright (c) 2001 by the Free Pascal development team

    This include file contains the implementation for variants
    support in FPC as far as it is part of the system unit

    See the file COPYING.FPC, included in this distribution,
    for details about the copyright.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 **********************************************************************}

var
   variantmanager : tvariantmanager;

procedure printmissingvariantunit;
  begin
    writeln(stderr);
    writeln(stderr,'Program needs probably the variants unit.');
    writeln(stderr,'Include the variants unit in your uses statements');
    writeln(stderr,'as one of the first units.');
    writeln(stderr);
  end;


procedure invalidvariantop;
  begin
     printmissingvariantunit;
     HandleErrorFrame(221,get_frame);
  end;


procedure invalidvariantopnovariants;
  begin
    printmissingvariantunit;
    HandleErrorFrame(221,get_frame);
  end;


procedure vardisperror;
  begin
    printmissingvariantunit;
    HandleErrorFrame(222,get_frame);
  end;


{ ---------------------------------------------------------------------
    Compiler helper routines.
  ---------------------------------------------------------------------}

procedure varclear(var v : tvardata);
begin
   if not(v.vtype in [varempty,varerror,varnull]) then
     invalidvariantop;
end;


procedure variant_init(var v : tvardata);[Public,Alias:'FPC_VARIANT_INIT'];
  begin
     { calling the variant manager here is a problem because the static/global variants
       are initialized while the variant manager isn't assigned }
     fillchar(v,sizeof(variant),0);
  end;


procedure variant_clear(var v : tvardata);[Public,Alias:'FPC_VARIANT_CLEAR'];
  begin
    if assigned(VarClearProc) then
      VarClearProc(v);
  end;


procedure variant_addref(var v : tvardata);[Public,Alias:'FPC_VARIANT_ADDREF'];
  begin
    if assigned(VarAddRefProc) then
      VarAddRefProc(v);
  end;

{ using pointers as argument here makes life for the compiler easier }
procedure fpc_variant_copy(d,s : pointer);compilerproc;
  begin
    if assigned(VarCopyProc) then
      VarCopyProc(tvardata(d^),tvardata(s^));
  end;


Procedure fpc_write_text_variant(Len : Longint;var f : Text;const v : variant); iocheck; [Public,Alias:'FPC_WRITE_TEXT_VARIANT']; compilerproc;
  begin
    if (InOutRes<>0) then
     exit;
    case TextRec(f).mode of
      { fmAppend gets changed to fmOutPut in do_open (JM) }
      fmOutput:
        if len=-1 then
          variantmanager.write0variant(f,v)
        else
          variantmanager.writevariant(f,v,len);
      fmInput:
        InOutRes:=105
      else InOutRes:=103;
    end;
  end;


procedure fpc_vararray_get(var d : variant;const s : variant;indices : psizeint;len : sizeint);compilerproc;
  begin
    d:=variantmanager.vararrayget(s,len,indices);
  end;


procedure fpc_vararray_put(var d : variant;const s : variant;indices : psizeint;len : sizeint);compilerproc;
  begin
    variantmanager.vararrayput(d,s,len,indices);
  end;


function fpc_variant_to_dynarray(const v : variant;typeinfo : pointer) : pointer;compilerproc;
  begin
    result:=nil;
    variantmanager.vartodynarray(result,v,typeinfo);
  end;


function fpc_dynarray_to_variant(dynarr : pointer;typeinfo : pointer) : variant;compilerproc;
  begin
    variantmanager.varfromdynarray(result,dynarr,typeinfo);
  end;


function fpc_variant_to_interface(const v : variant) : iinterface;compilerproc;
  begin
    variantmanager.vartointf(result,v);
  end;


function fpc_interface_to_variant(const i : iinterface) : variant;compilerproc;
  begin
    variantmanager.varfromintf(result,i);
  end;


{ ---------------------------------------------------------------------
    Overloaded operators.
  ---------------------------------------------------------------------}


{ Integer }

operator :=(const source : byte) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
begin
  Variantmanager.varfromInt(Dest,Source,1);
end;


operator :=(const source : shortint) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
begin
  Variantmanager.varfromInt(Dest,Source,-1);
end;


operator :=(const source : word) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
begin
  Variantmanager.varfromInt(Dest,Source,2);
end;


operator :=(const source : smallint) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
begin
  Variantmanager.varfromInt(Dest,Source,-2);
end;


operator :=(const source : dword) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
begin
  Variantmanager.varfromInt(Dest,Source,4);
end;


operator :=(const source : longint) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
begin
  Variantmanager.varfromInt(Dest,Source,-4);
end;


operator :=(const source : qword) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
begin
  Variantmanager.varfromWord64(Dest,Source);
end;


operator :=(const source : int64) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
begin
  Variantmanager.varfromInt64(Dest,Source);
end;

{ Boolean }

operator :=(const source : boolean) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
begin
  Variantmanager.varfromBool(Dest,Source);
end;


operator :=(const source : wordbool) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}

begin
  Variantmanager.varfromBool(Dest,Boolean(Source));
end;


operator :=(const source : longbool) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}

begin
  Variantmanager.varfromBool(Dest,Boolean(Source));
end;


{ Chars }

operator :=(const source : char) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}

begin
  VariantManager.VarFromPStr(Dest,Source);
end;


operator :=(const source : widechar) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}

begin
  VariantManager.VarFromWStr(Dest,Source);
end;

{ Strings }

operator :=(const source : shortstring) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}

begin
  VariantManager.VarFromPStr(Dest,Source);
end;


operator :=(const source : ansistring) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}

begin
  VariantManager.VarFromLStr(Dest,Source);
end;


operator :=(const source : widestring) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}

begin
  VariantManager.VarFromWStr(Dest,Source);
end;

{ Floats }

{$ifdef SUPPORT_SINGLE}
operator :=(const source : single) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
begin
  VariantManager.VarFromReal(Dest,Source);
end;
{$endif SUPPORT_SINGLE}


{$ifdef SUPPORT_DOUBLE}
operator :=(const source : double) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
begin
  VariantManager.VarFromReal(Dest,Source);
end;
{$endif SUPPORT_DOUBLE}


{$ifdef SUPPORT_EXTENDED}
operator :=(const source : extended) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
begin
  VariantManager.VarFromReal(Dest,Source);
end;
{$endif SUPPORT_EXTENDED}


{$ifdef SUPPORT_COMP}
Operator :=(const source : comp) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
begin
  VariantManager.VarFromReal(Dest,Source);
end;
{$endif SUPPORT_COMP}


{ Misc. }
operator :=(const source : currency) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    VariantManager.VarFromCurr(Dest,Source);
  end;


operator :=(const source : tdatetime) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    VariantManager.VarFromTDateTime(Dest,Source);
  end;


operator :=(const source : terror) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    Variantmanager.varfromInt(Dest,Source,-sizeof(terror));
  end;
  
{**********************************************************************
                       from Variant assignments
 **********************************************************************}

{ Integer }

operator :=(const source : variant) dest : byte;{$ifdef SYSTEMINLINE}inline;{$endif}

begin
  dest:=variantmanager.vartoint(source);
end;


operator :=(const source : variant) dest : shortint;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartoint(source);
  end;


operator :=(const source : variant) dest : word;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartoint(source);
  end;


operator :=(const source : variant) dest : smallint;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartoint(source);
  end;


operator :=(const source : variant) dest : dword;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartoint(source);
  end;


operator :=(const source : variant) dest : longint;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartoint(source);
  end;


operator :=(const source : variant) dest : qword;{$ifdef SYSTEMINLINE}inline;{$endif}

begin
  dest:=variantmanager.vartoword64(source);
end;


operator :=(const source : variant) dest : int64;{$ifdef SYSTEMINLINE}inline;{$endif}

begin
  dest:=variantmanager.vartoint64(source);
end;


{ Boolean }

operator :=(const source : variant) dest : boolean;{$ifdef SYSTEMINLINE}inline;{$endif}

begin
  dest:=variantmanager.vartobool(source);
end;


operator :=(const source : variant) dest : wordbool;{$ifdef SYSTEMINLINE}inline;{$endif}

begin
  dest:=variantmanager.vartobool(source);
end;


operator :=(const source : variant) dest : longbool;{$ifdef SYSTEMINLINE}inline;{$endif}

begin
   dest:=variantmanager.vartobool(source);
end;


{ Chars }

operator :=(const source : variant) dest : char;{$ifdef SYSTEMINLINE}inline;{$endif}

Var
  S : String;

begin
  VariantManager.VarToPStr(S,Source);
  If Length(S)>0 then
    Dest:=S[1];
end;


operator :=(const source : variant) dest : widechar;{$ifdef SYSTEMINLINE}inline;{$endif}

Var
  WS : WideString;

begin
  VariantManager.VarToWStr(WS,Source);
  If Length(WS)>0 then
    Dest:=WS[1];
end;


{ Strings }

operator :=(const source : variant) dest : shortstring;{$ifdef SYSTEMINLINE}inline;{$endif}

begin
  VariantManager.VarToPStr(Dest,Source);
end;

operator :=(const source : variant) dest : ansistring;{$ifdef SYSTEMINLINE}inline;{$endif}

begin
  VariantManager.vartolstr(dest,source);
end;

operator :=(const source : variant) dest : widestring;{$ifdef SYSTEMINLINE}inline;{$endif}

begin
  variantmanager.vartowstr(dest,source);
end;

{ Floats }

{$ifdef SUPPORT_SINGLE}
operator :=(const source : variant) dest : single;{$ifdef SYSTEMINLINE}inline;{$endif}
begin
  dest:=variantmanager.vartoreal(source);
end;
{$endif SUPPORT_SINGLE}


{$ifdef SUPPORT_DOUBLE}
operator :=(const source : variant) dest : double;{$ifdef SYSTEMINLINE}inline;{$endif}
begin
  dest:=variantmanager.vartoreal(source);
end;
{$endif SUPPORT_DOUBLE}


{$ifdef SUPPORT_EXTENDED}
operator :=(const source : variant) dest : extended;{$ifdef SYSTEMINLINE}inline;{$endif}
begin
  dest:=variantmanager.vartoreal(source);
end;
{$endif SUPPORT_EXTENDED}


{$ifdef SUPPORT_COMP}
operator :=(const source : variant) dest : comp;{$ifdef SYSTEMINLINE}inline;{$endif}
begin
  dest:=comp(variantmanager.vartoreal(source));
end;
{$endif SUPPORT_COMP}


{ Misc. }
operator :=(const source : variant) dest : currency;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartocurr(source);
  end;


operator :=(const source : variant) dest : tdatetime;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartotdatetime(source);
  end;


operator :=(const source : olevariant) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    tvardata(result):=tvardata(source);
  end;


operator :=(const source : variant) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.olevarfromvar(dest,source);
  end;


operator :=(const source : variant) dest : terror;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartoint(source);
  end;
{**********************************************************************
                               Operators
 **********************************************************************}

operator or(const op1,op2 : variant) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
     dest:=op1;
     variantmanager.varop(dest,op2,opor);
  end;

operator and(const op1,op2 : variant) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
     dest:=op1;
     variantmanager.varop(dest,op2,opand);
  end;

operator xor(const op1,op2 : variant) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
     dest:=op1;
     variantmanager.varop(dest,op2,opxor);
  end;

operator not(const op : variant) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
     dest:=op;
     variantmanager.varnot(dest);
  end;

operator shl(const op1,op2 : variant) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
     dest:=op1;
     variantmanager.varop(dest,op2,opshiftleft);
  end;

operator shr(const op1,op2 : variant) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
     dest:=op1;
     variantmanager.varop(dest,op2,opshiftright);
  end;

operator +(const op1,op2 : variant) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
     dest:=op1;
     variantmanager.varop(dest,op2,opadd);
  end;

operator -(const op1,op2 : variant) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
     dest:=op1;
     variantmanager.varop(dest,op2,opsubtract);
  end;

operator *(const op1,op2 : variant) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
     dest:=op1;
     variantmanager.varop(dest,op2,opmultiply);
  end;

operator /(const op1,op2 : variant) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
     dest:=op1;
     variantmanager.varop(dest,op2,opdivide);
  end;

operator **(const op1,op2 : variant) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
     dest:=op1;
     variantmanager.varop(dest,op2,oppower);
  end;

operator div(const op1,op2 : variant) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
     dest:=op1;
     variantmanager.varop(dest,op2,opintdivide);
  end;

operator mod(const op1,op2 : variant) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
     dest:=op1;
     variantmanager.varop(dest,op2,opmodulus);
  end;

operator -(const op : variant) dest : variant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
     dest:=op;
     variantmanager.varneg(dest);
  end;

operator =(const op1,op2 : variant) dest : boolean;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
     dest:=variantmanager.cmpop(op1,op2,opcmpeq);
  end;

operator <(const op1,op2 : variant) dest : boolean;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
     dest:=variantmanager.cmpop(op1,op2,opcmplt);
  end;

operator >(const op1,op2 : variant) dest : boolean;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
     dest:=variantmanager.cmpop(op1,op2,opcmpgt);
  end;

operator >=(const op1,op2 : variant) dest : boolean;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
     dest:=variantmanager.cmpop(op1,op2,opcmpge);
  end;

operator <=(const op1,op2 : variant) dest : boolean;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
     dest:=variantmanager.cmpop(op1,op2,opcmplt);
  end;

procedure VarArrayRedim(var A: Variant; HighBound: SizeInt);
  begin
    variantmanager.vararrayredim(a,highbound);
  end;

procedure VarCast(var dest : variant;const source : variant;vartype : longint);

  begin
    variantmanager.varcast(dest,source,vartype);
  end;


{**********************************************************************
                        from OLEVariant assignments
 **********************************************************************}
{ Integer }
operator :=(const source : olevariant) dest : byte;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    { cast away olevar to var conversion and avoid
      endless recursion }
    dest:=variantmanager.vartoint(variant(tvardata(source)));
  end;


operator :=(const source : olevariant) dest : shortint;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartoint(variant(tvardata(source)));
  end;


operator :=(const source : olevariant) dest : word;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartoint(variant(tvardata(source)));
  end;


operator :=(const source : olevariant) dest : smallint;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartoint(variant(tvardata(source)));
  end;


operator :=(const source : olevariant) dest : dword;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartoint(variant(tvardata(source)));
  end;


operator :=(const source : olevariant) dest : longint;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartoint(variant(tvardata(source)));
  end;


operator :=(const source : olevariant) dest : qword;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartoint64(variant(tvardata(source)));
  end;


operator :=(const source : olevariant) dest : int64;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartoword64(variant(tvardata(source)));
  end;


{ Boolean }
operator :=(const source : olevariant) dest : boolean;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartobool(variant(tvardata(source)));
  end;


operator :=(const source : olevariant) dest : wordbool;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartobool(variant(tvardata(source)));
  end;


operator :=(const source : olevariant) dest : longbool;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartobool(variant(tvardata(source)));
  end;


{ Chars }
operator :=(const source : olevariant) dest : char;{$ifdef SYSTEMINLINE}inline;{$endif}
  var
    S : String;
  begin
    VariantManager.VarToPStr(S,Source);
    If Length(S)>0 then
      Dest:=S[1]
    else
      Dest:=#0;
  end;


operator :=(const source : olevariant) dest : widechar;{$ifdef SYSTEMINLINE}inline;{$endif}
  Var
    WS : WideString;
  begin
    VariantManager.VarToWStr(WS,Source);
    If Length(WS)>0 then
      Dest:=WS[1]
    else
      Dest:=#0;
  end;


{ Strings }
operator :=(const source : olevariant) dest : shortstring;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.vartopstr(dest,variant(tvardata(source)));
  end;


operator :=(const source : olevariant) dest : ansistring;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.vartolstr(dest,variant(tvardata(source)));
  end;


operator :=(const source : olevariant) dest : widestring;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.vartowstr(dest,variant(tvardata(source)));
  end;


{ Floats }
{$ifdef SUPPORT_SINGLE}
operator :=(const source : olevariant) dest : single;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartoreal(variant(tvardata(source)));
  end;
{$endif SUPPORT_SINGLE}


{$ifdef SUPPORT_DOUBLE}
operator :=(const source : olevariant) dest : double;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartoreal(variant(tvardata(source)));
  end;
{$endif SUPPORT_DOUBLE}


{$ifdef SUPPORT_EXTENDED}
operator :=(const source : olevariant) dest : extended;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartoreal(variant(tvardata(source)));
  end;
{$endif SUPPORT_EXTENDED}


{$ifdef SUPPORT_COMP}
operator :=(const source : olevariant) dest : comp;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartoreal(variant(tvardata(source)));
  end;
{$endif SUPPORT_COMP}


{ Misc. }
operator :=(const source : olevariant) dest : currency;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartocurr(variant(tvardata(source)));
  end;


operator :=(const source : olevariant) dest : tdatetime;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartotdatetime(variant(tvardata(source)));
  end;


operator :=(const source : olevariant) dest : terror;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    dest:=variantmanager.vartoint(variant(tvardata(source)));
  end;

{**********************************************************************
                          to OLEVariant assignments
 **********************************************************************}

operator :=(const source : byte) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.olevarfromint(dest,source,1);
  end;


operator :=(const source : shortint) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.olevarfromint(dest,source,-1);
  end;


operator :=(const source : word) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.olevarfromint(dest,source,2);
  end;


operator :=(const source : smallint) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.olevarfromint(dest,source,-2);
  end;


operator :=(const source : dword) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.olevarfromint(dest,source,4);
  end;


operator :=(const source : longint) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.olevarfromint(dest,source,-4);
  end;


operator :=(const source : qword) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.olevarfromint(dest,source,8);
  end;


operator :=(const source : int64) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.olevarfromint(dest,source,-8);
  end;

{ Boolean }
operator :=(const source : boolean) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.varfromBool(variant(tvardata(dest)),Source);
   end;


operator :=(const source : wordbool) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.varfromBool(variant(tvardata(Dest)),Source);
   end;


operator :=(const source : longbool) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.varfromBool(variant(tvardata(Dest)),Source);
   end;


{ Chars }
operator :=(const source : char) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.olevarfrompstr(dest,source);
  end;


operator :=(const source : widechar) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.varfromwstr(variant(tvardata(dest)),source);
  end;


{ Strings }
operator :=(const source : shortstring) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.olevarfrompstr(dest,source);
  end;


operator :=(const source : ansistring) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.olevarfromlstr(dest,source);
  end;


operator :=(const source : widestring) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.varfromwstr(variant(tvardata(dest)),source);
  end;


{ Floats }
{$ifdef SUPPORT_SINGLE}
operator :=(const source : single) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.varfromreal(variant(tvardata(dest)),source);
  end;
{$endif SUPPORT_SINGLE}


{$ifdef SUPPORT_DOUBLE}
operator :=(const source : double) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.varfromreal(variant(tvardata(dest)),source);
  end;
{$endif SUPPORT_DOUBLE}


{$ifdef SUPPORT_EXTENDED}
operator :=(const source : extended) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.varfromreal(variant(tvardata(dest)),source);
  end;
{$endif SUPPORT_EXTENDED}


{$ifdef SUPPORT_COMP}
operator :=(const source : comp) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.varfromreal(variant(tvardata(dest)),source);
  end;
{$endif SUPPORT_COMP}


{ Misc. }
operator :=(const source : currency) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.varfromcurr(variant(tvardata(dest)),source);
  end;


operator :=(const source : tdatetime) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.varfromtdatetime(variant(tvardata(dest)),source);
  end;


operator :=(const source : terror) dest : olevariant;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    variantmanager.olevarfromint(dest,source,-sizeof(terror));
  end;
{**********************************************************************
                      Variant manager functions
 **********************************************************************}

procedure GetVariantManager(var VarMgr: TVariantManager);
begin
  VarMgr:=VariantManager;
end;

procedure SetVariantManager(const VarMgr: TVariantManager);
begin
  VariantManager:=VarMgr;
end;

function IsVariantManagerSet: Boolean;
var
   i : longint;
begin
   I:=0;
   Result:=True;
   While Result and (I<(sizeof(tvariantmanager) div sizeof(pointer))-1) do
     begin
       Result:=Pointer(ppointer(@variantmanager+i*sizeof(pointer))^)<>Pointer(@invalidvariantop);
       Inc(I);
     end;
end;


procedure initvariantmanager;
  var
     i : longint;
  begin
     VarDispProc:=@vardisperror;
     DispCallByIDProc:=@vardisperror;
     tvardata(Unassigned).VType:=varEmpty;
     tvardata(Null).VType:=varNull;
     for i:=0 to (sizeof(tvariantmanager) div sizeof(pointer))-1 do
       ppointer(@variantmanager+i*sizeof(pointer))^:=@invalidvariantopnovariants;
     pointer(variantmanager.varclear):=@varclear
  end;
