zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

comutil.h (32109B) - Raw


      1 /**
      2  * This file has no copyright assigned and is placed in the Public Domain.
      3  * This file is part of the mingw-w64 runtime package.
      4  * No warranty is given; refer to the file DISCLAIMER.PD within this package.
      5  */
      6 #ifndef _INC_COMUTIL
      7 #define _INC_COMUTIL
      8 
      9 #include <ole2.h>
     10 #include <stdio.h>
     11 
     12 #ifndef _COM_ASSERT
     13 #define _COM_ASSERT(x) ((void)0)
     14 #endif
     15 
     16 #define _COM_MEMCPY_S(dest,destsize,src,count) memcpy(dest,src,count)
     17 
     18 /* Use of wsprintf might be impossible, if strsafe.h is included. */
     19 #ifndef __STDC_SECURE_LIB__
     20 #define _COM_PRINTF_S_1(dest,destsize,format,arg1) wsprintf(dest,format,arg1)
     21 #elif defined(UNICODE)
     22 #define _COM_PRINTF_S_1(dest,destsize,format,arg1) swprintf_s(dest,destsize,format,arg1)
     23 #else
     24 #define _COM_PRINTF_S_1(dest,destsize,format,arg1) sprintf_s(dest,destsize,format,arg1)
     25 #endif
     26 
     27 #ifdef __cplusplus
     28 
     29 #pragma push_macro("new")
     30 #undef new
     31 
     32 #ifndef WINAPI
     33 #if defined(_ARM_)
     34 #define WINAPI
     35 #else
     36 #define WINAPI __stdcall
     37 #endif
     38 #endif
     39 
     40 class _com_error;
     41 
     42 void WINAPI _com_issue_error(HRESULT);
     43 
     44 class _bstr_t;
     45 class _variant_t;
     46 
     47 namespace _com_util {
     48   inline void CheckError(HRESULT hr) {
     49     if(FAILED(hr)) { _com_issue_error(hr); }
     50   }
     51 }
     52 
     53 namespace _com_util {
     54   BSTR WINAPI ConvertStringToBSTR(const char *pSrc);
     55   char *WINAPI ConvertBSTRToString(BSTR pSrc);
     56 }
     57 
     58 class _bstr_t {
     59 public:
     60   _bstr_t() throw();
     61   _bstr_t(const _bstr_t &s) throw();
     62   _bstr_t(const char *s);
     63   _bstr_t(const wchar_t *s);
     64   _bstr_t(const _variant_t &var);
     65   _bstr_t(BSTR bstr,bool fCopy);
     66   ~_bstr_t() throw();
     67   _bstr_t &operator=(const _bstr_t &s) throw();
     68   _bstr_t &operator=(const char *s);
     69   _bstr_t &operator=(const wchar_t *s);
     70   _bstr_t &operator=(const _variant_t &var);
     71   _bstr_t &operator+=(const _bstr_t &s);
     72   _bstr_t operator+(const _bstr_t &s) const;
     73   friend _bstr_t operator+(const char *s1,const _bstr_t &s2);
     74   friend _bstr_t operator+(const wchar_t *s1,const _bstr_t &s2);
     75   operator const wchar_t *() const throw();
     76   operator wchar_t *() const throw();
     77   operator const char *() const;
     78   operator char *() const;
     79   bool operator!() const throw();
     80   bool operator==(const _bstr_t &str) const throw();
     81   bool operator!=(const _bstr_t &str) const throw();
     82   bool operator<(const _bstr_t &str) const throw();
     83   bool operator>(const _bstr_t &str) const throw();
     84   bool operator<=(const _bstr_t &str) const throw();
     85   bool operator>=(const _bstr_t &str) const throw();
     86   BSTR copy(bool fCopy = true) const;
     87   unsigned int length() const throw();
     88   void Assign(BSTR s);
     89   BSTR &GetBSTR();
     90   BSTR *GetAddress();
     91   void Attach(BSTR s);
     92   BSTR Detach() throw();
     93 private:
     94   class Data_t {
     95   public:
     96     Data_t(const char *s);
     97     Data_t(const wchar_t *s);
     98     Data_t(BSTR bstr,bool fCopy);
     99     Data_t(const _bstr_t &s1,const _bstr_t &s2);
    100     unsigned __LONG32 AddRef() throw();
    101     unsigned __LONG32 Release() throw();
    102     unsigned __LONG32 RefCount() const throw();
    103     operator const wchar_t *() const throw();
    104     operator const char *() const;
    105     const wchar_t *GetWString() const throw();
    106     wchar_t *&GetWString() throw();
    107     const char *GetString() const;
    108     BSTR Copy() const;
    109     void Assign(BSTR s);
    110     void Attach(BSTR s) throw();
    111     unsigned int Length() const throw();
    112     int Compare(const Data_t &str) const throw();
    113     void *operator new(size_t sz);
    114   private:
    115     BSTR m_wstr;
    116     mutable char *m_str;
    117     unsigned __LONG32 m_RefCount;
    118     Data_t() throw();
    119     Data_t(const Data_t &s) throw();
    120     ~Data_t() throw();
    121     void _Free() throw();
    122   };
    123 private:
    124   Data_t *m_Data;
    125 private:
    126   void _AddRef() throw();
    127   void _Free() throw();
    128   int _Compare(const _bstr_t &str) const throw();
    129 };
    130 
    131 inline _bstr_t::_bstr_t() throw() : m_Data(NULL) { }
    132 
    133 inline _bstr_t::_bstr_t(const _bstr_t &s) throw() : m_Data(s.m_Data) { _AddRef(); }
    134 
    135 inline _bstr_t::_bstr_t(const char *s) : m_Data(new Data_t(s)) {
    136   if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
    137 }
    138 
    139 inline _bstr_t::_bstr_t(const wchar_t *s) : m_Data(new Data_t(s)) {
    140   if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
    141 }
    142 
    143 inline _bstr_t::_bstr_t(BSTR bstr,bool fCopy) : m_Data(new Data_t(bstr,fCopy)) {
    144   if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
    145 }
    146 
    147 inline _bstr_t::~_bstr_t() throw() { _Free(); }
    148 
    149 inline _bstr_t &_bstr_t::operator=(const _bstr_t &s) throw() {
    150   if(this!=&s) {
    151     _Free();
    152     m_Data = s.m_Data;
    153     _AddRef();
    154   }
    155   return *this;
    156 }
    157 
    158 inline _bstr_t &_bstr_t::operator=(const char *s) {
    159   _COM_ASSERT(!s || static_cast<const char *>(*this)!=s);
    160   if(!s || static_cast<const char *>(*this)!=s) {
    161     _Free();
    162     m_Data = new Data_t(s);
    163     if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
    164   }
    165   return *this;
    166 }
    167 
    168 inline _bstr_t &_bstr_t::operator=(const wchar_t *s) {
    169   _COM_ASSERT(!s || static_cast<const wchar_t *>(*this)!=s);
    170   if(!s || static_cast<const wchar_t *>(*this)!=s) {
    171     _Free();
    172     m_Data = new Data_t(s);
    173     if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
    174   }
    175   return *this;
    176 }
    177 
    178 inline _bstr_t &_bstr_t::operator+=(const _bstr_t &s) {
    179   Data_t *newData = new Data_t(*this,s);
    180   if(!newData) { _com_issue_error(E_OUTOFMEMORY); }
    181   else {
    182     _Free();
    183     m_Data = newData;
    184   }
    185   return *this;
    186 }
    187 
    188 inline _bstr_t _bstr_t::operator+(const _bstr_t &s) const {
    189   _bstr_t b = *this;
    190   b += s;
    191   return b;
    192 }
    193 
    194 inline _bstr_t operator+(const char *s1,const _bstr_t &s2) {
    195   _bstr_t b = s1;
    196   b += s2;
    197   return b;
    198 }
    199 
    200 inline _bstr_t operator+(const wchar_t *s1,const _bstr_t &s2) {
    201   _bstr_t b = s1;
    202   b += s2;
    203   return b;
    204 }
    205 
    206 inline _bstr_t::operator const wchar_t *() const throw() { return (m_Data!=NULL) ? m_Data->GetWString() : NULL; }
    207 inline _bstr_t::operator wchar_t *() const throw() { return const_cast<wchar_t *>((m_Data!=NULL) ? m_Data->GetWString() : NULL); }
    208 inline _bstr_t::operator const char *() const { return (m_Data!=NULL) ? m_Data->GetString() : NULL; }
    209 inline _bstr_t::operator char *() const { return const_cast<char *>((m_Data!=NULL) ? m_Data->GetString() : NULL); }
    210 inline bool _bstr_t::operator!() const throw() { return (m_Data!=NULL) ? !m_Data->GetWString() : true; }
    211 inline bool _bstr_t::operator==(const _bstr_t &str) const throw() { return _Compare(str)==0; }
    212 inline bool _bstr_t::operator!=(const _bstr_t &str) const throw() { return _Compare(str)!=0; }
    213 inline bool _bstr_t::operator<(const _bstr_t &str) const throw() { return _Compare(str)<0; }
    214 inline bool _bstr_t::operator>(const _bstr_t &str) const throw() { return _Compare(str)>0; }
    215 inline bool _bstr_t::operator<=(const _bstr_t &str) const throw() { return _Compare(str)<=0; }
    216 inline bool _bstr_t::operator>=(const _bstr_t &str) const throw() { return _Compare(str)>=0; }
    217 inline BSTR _bstr_t::copy(bool fCopy) const { return (m_Data!=NULL) ? (fCopy ? m_Data->Copy() : m_Data->GetWString()) : NULL; }
    218 inline unsigned int _bstr_t::length() const throw() { return (m_Data!=NULL) ? m_Data->Length() : 0; }
    219 inline void _bstr_t::Assign(BSTR s) {
    220   _COM_ASSERT(!s || !m_Data || m_Data->GetWString()!=s);
    221   if(!s || !m_Data || m_Data->GetWString()!=s) {
    222     _Free();
    223     m_Data = new Data_t(s,TRUE);
    224     if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
    225   }
    226 }
    227 
    228 inline BSTR &_bstr_t::GetBSTR() {
    229   if(!m_Data) {
    230     m_Data = new Data_t(0,FALSE);
    231     if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
    232   }
    233   return m_Data->GetWString();
    234 }
    235 
    236 inline BSTR *_bstr_t::GetAddress() {
    237   Attach(0);
    238   return &m_Data->GetWString();
    239 }
    240 
    241 inline void _bstr_t::Attach(BSTR s) {
    242   _Free();
    243   m_Data = new Data_t(s,FALSE);
    244   if(!m_Data) { _com_issue_error(E_OUTOFMEMORY); }
    245 }
    246 
    247 inline BSTR _bstr_t::Detach() throw () {
    248   _COM_ASSERT(m_Data!=NULL && m_Data->RefCount()==1);
    249   if(m_Data!=NULL && m_Data->RefCount()==1) {
    250     BSTR b = m_Data->GetWString();
    251     m_Data->GetWString() = NULL;
    252     _Free();
    253     return b;
    254   } else {
    255     _com_issue_error(E_POINTER);
    256     return NULL;
    257   }
    258 }
    259 
    260 inline void _bstr_t::_AddRef() throw() {
    261   if(m_Data!=NULL) m_Data->AddRef();
    262 }
    263 
    264 inline void _bstr_t::_Free() throw() {
    265   if(m_Data!=NULL) {
    266     m_Data->Release();
    267     m_Data = NULL;
    268   }
    269 }
    270 
    271 inline int _bstr_t::_Compare(const _bstr_t &str) const throw() {
    272   if(m_Data==str.m_Data) return 0;
    273   if(!m_Data) return -1;
    274   if(!str.m_Data) return 1;
    275   return m_Data->Compare(*str.m_Data);
    276 }
    277 
    278 inline _bstr_t::Data_t::Data_t(const char *s) : m_str(NULL),m_RefCount(1) {
    279   m_wstr = _com_util::ConvertStringToBSTR(s);
    280 }
    281 
    282 inline _bstr_t::Data_t::Data_t(const wchar_t *s) : m_str(NULL),m_RefCount(1) {
    283   m_wstr = ::SysAllocString(s);
    284   if(!m_wstr && s!=NULL) { _com_issue_error(E_OUTOFMEMORY); }
    285 }
    286 
    287 inline _bstr_t::Data_t::Data_t(BSTR bstr,bool fCopy) : m_str(NULL),m_RefCount(1) {
    288   if(fCopy && bstr!=NULL) {
    289     m_wstr = ::SysAllocStringByteLen(reinterpret_cast<char *>(bstr),::SysStringByteLen(bstr));
    290     if(!m_wstr) { _com_issue_error(E_OUTOFMEMORY); }
    291   } else m_wstr = bstr;
    292 }
    293 
    294 inline _bstr_t::Data_t::Data_t(const _bstr_t &s1,const _bstr_t &s2) : m_str(NULL),m_RefCount(1) {
    295   const unsigned int l1 = s1.length();
    296   const unsigned int l2 = s2.length();
    297   m_wstr = ::SysAllocStringByteLen(NULL,(l1 + l2) *sizeof(wchar_t));
    298   if(!m_wstr) {
    299     _com_issue_error(E_OUTOFMEMORY);
    300     return;
    301   }
    302   const wchar_t *wstr1 = static_cast<const wchar_t *>(s1);
    303   if(wstr1!=NULL) {
    304     _COM_MEMCPY_S(m_wstr,(l1 + l2 + 1) *sizeof(wchar_t),wstr1,(l1 + 1) *sizeof(wchar_t));
    305   }
    306   const wchar_t *wstr2 = static_cast<const wchar_t *>(s2);
    307   if(wstr2!=NULL) {
    308     _COM_MEMCPY_S(m_wstr + l1,(l2 + 1) *sizeof(wchar_t),wstr2,(l2 + 1) *sizeof(wchar_t));
    309   }
    310 }
    311 
    312 inline unsigned __LONG32 _bstr_t::Data_t::AddRef() throw() {
    313   InterlockedIncrement(reinterpret_cast<LONG*>(&m_RefCount));
    314   return m_RefCount;
    315 }
    316 
    317 inline unsigned __LONG32 _bstr_t::Data_t::Release() throw() {
    318   unsigned __LONG32 cRef = InterlockedDecrement(reinterpret_cast<LONG*>(&m_RefCount));
    319   if(cRef==0) delete this;
    320   return cRef;
    321 }
    322 
    323 inline unsigned __LONG32 _bstr_t::Data_t::RefCount() const throw() { return m_RefCount; }
    324 inline _bstr_t::Data_t::operator const wchar_t *() const throw() { return m_wstr; }
    325 inline _bstr_t::Data_t::operator const char *() const { return GetString(); }
    326 inline const wchar_t *_bstr_t::Data_t::GetWString() const throw() { return m_wstr; }
    327 inline wchar_t *&_bstr_t::Data_t::GetWString() throw() { return m_wstr; }
    328 inline const char *_bstr_t::Data_t::GetString() const {
    329   if(!m_str) m_str = _com_util::ConvertBSTRToString(m_wstr);
    330   return m_str;
    331 }
    332 inline BSTR _bstr_t::Data_t::Copy() const {
    333   if(m_wstr!=NULL) {
    334     BSTR bstr = ::SysAllocStringByteLen(reinterpret_cast<char *>(m_wstr),::SysStringByteLen(m_wstr));
    335     if(!bstr) { _com_issue_error(E_OUTOFMEMORY); }
    336     return bstr;
    337   }
    338   return NULL;
    339 }
    340 inline void _bstr_t::Data_t::Assign(BSTR s) {
    341   _Free();
    342   if(s!=NULL) {
    343     m_wstr = ::SysAllocStringByteLen(reinterpret_cast<char *>(s),::SysStringByteLen(s));
    344     m_str = 0;
    345   }
    346 }
    347 inline void _bstr_t::Data_t::Attach(BSTR s) throw() {
    348   _Free();
    349   m_wstr = s;
    350   m_str = 0;
    351   m_RefCount = 1;
    352 }
    353 inline unsigned int _bstr_t::Data_t::Length() const throw() { return m_wstr ? ::SysStringLen(m_wstr) : 0; }
    354 inline int _bstr_t::Data_t::Compare(const _bstr_t::Data_t &str) const throw() {
    355   if(!m_wstr) return str.m_wstr ? -1 : 0;
    356   if(!str.m_wstr) return 1;
    357   const unsigned int l1 = ::SysStringLen(m_wstr);
    358   const unsigned int l2 = ::SysStringLen(str.m_wstr);
    359   unsigned int len = l1;
    360   if(len>l2) len = l2;
    361   BSTR bstr1 = m_wstr;
    362   BSTR bstr2 = str.m_wstr;
    363   while (len-->0) {
    364     if(*bstr1++!=*bstr2++) return bstr1[-1] - bstr2[-1];
    365   }
    366   return (l1<l2) ? -1 : (l1==l2) ? 0 : 1;
    367 }
    368 
    369 #ifdef _COM_OPERATOR_NEW_THROWS
    370 inline void *_bstr_t::Data_t::operator new(size_t sz) {
    371   try {
    372     return ::operator new(sz);
    373   } catch (...) {
    374     return NULL;
    375   }
    376 }
    377 #else
    378 inline void *_bstr_t::Data_t::operator new(size_t sz) {
    379   return ::operator new(sz);
    380 }
    381 #endif
    382 
    383 inline _bstr_t::Data_t::~Data_t() throw() { _Free(); }
    384 inline void _bstr_t::Data_t::_Free() throw() {
    385   if(m_wstr!=NULL) ::SysFreeString(m_wstr);
    386   if(m_str!=NULL) delete [] m_str;
    387 }
    388 
    389 class _variant_t : public ::tagVARIANT {
    390 public:
    391   _variant_t() throw();
    392   _variant_t(const VARIANT &varSrc);
    393   _variant_t(const VARIANT *pSrc);
    394   _variant_t(const _variant_t &varSrc);
    395   _variant_t(VARIANT &varSrc,bool fCopy);
    396   _variant_t(short sSrc,VARTYPE vtSrc = VT_I2);
    397   _variant_t(__LONG32 lSrc,VARTYPE vtSrc = VT_I4);
    398   _variant_t(float fltSrc) throw();
    399   _variant_t(double dblSrc,VARTYPE vtSrc = VT_R8);
    400   _variant_t(const CY &cySrc) throw();
    401   _variant_t(const _bstr_t &bstrSrc);
    402   _variant_t(const wchar_t *pSrc);
    403   _variant_t(const char *pSrc);
    404   _variant_t(IDispatch *pSrc,bool fAddRef = true) throw();
    405   _variant_t(bool boolSrc) throw();
    406   _variant_t(IUnknown *pSrc,bool fAddRef = true) throw();
    407   _variant_t(const DECIMAL &decSrc) throw();
    408   _variant_t(BYTE bSrc) throw();
    409   _variant_t(char cSrc) throw();
    410   _variant_t(unsigned short usSrc) throw();
    411   _variant_t(unsigned __LONG32 ulSrc) throw();
    412 #ifndef __CYGWIN__
    413   _variant_t(int iSrc) throw();
    414   _variant_t(unsigned int uiSrc) throw();
    415 #endif
    416   __MINGW_EXTENSION _variant_t(__int64 i8Src) throw();
    417   __MINGW_EXTENSION _variant_t(unsigned __int64 ui8Src) throw();
    418   ~_variant_t() throw();
    419   operator short() const;
    420   operator __LONG32() const;
    421   operator float() const;
    422   operator double() const;
    423   operator CY() const;
    424   operator _bstr_t() const;
    425   operator IDispatch*() const;
    426   operator bool() const;
    427   operator IUnknown*() const;
    428   operator DECIMAL() const;
    429   operator BYTE() const;
    430   operator VARIANT() const throw();
    431   operator char() const;
    432   operator unsigned short() const;
    433   operator unsigned __LONG32() const;
    434 #ifndef __CYGWIN__
    435   operator int() const;
    436   operator unsigned int() const;
    437 #endif
    438   __MINGW_EXTENSION operator __int64() const;
    439   __MINGW_EXTENSION operator unsigned __int64() const;
    440   _variant_t &operator=(const VARIANT &varSrc);
    441   _variant_t &operator=(const VARIANT *pSrc);
    442   _variant_t &operator=(const _variant_t &varSrc);
    443   _variant_t &operator=(short sSrc);
    444   _variant_t &operator=(__LONG32 lSrc);
    445   _variant_t &operator=(float fltSrc);
    446   _variant_t &operator=(double dblSrc);
    447   _variant_t &operator=(const CY &cySrc);
    448   _variant_t &operator=(const _bstr_t &bstrSrc);
    449   _variant_t &operator=(const wchar_t *pSrc);
    450   _variant_t &operator=(const char *pSrc);
    451   _variant_t &operator=(IDispatch *pSrc);
    452   _variant_t &operator=(bool boolSrc);
    453   _variant_t &operator=(IUnknown *pSrc);
    454   _variant_t &operator=(const DECIMAL &decSrc);
    455   _variant_t &operator=(BYTE bSrc);
    456   _variant_t &operator=(char cSrc);
    457   _variant_t &operator=(unsigned short usSrc);
    458   _variant_t &operator=(unsigned __LONG32 ulSrc);
    459 #ifndef __CYGWIN__
    460   _variant_t &operator=(int iSrc);
    461   _variant_t &operator=(unsigned int uiSrc);
    462 #endif
    463   __MINGW_EXTENSION _variant_t &operator=(__int64 i8Src);
    464   __MINGW_EXTENSION _variant_t &operator=(unsigned __int64 ui8Src);
    465   bool operator==(const VARIANT &varSrc) const throw();
    466   bool operator==(const VARIANT *pSrc) const throw();
    467   bool operator!=(const VARIANT &varSrc) const throw();
    468   bool operator!=(const VARIANT *pSrc) const throw();
    469   void Clear();
    470   void Attach(VARIANT &varSrc);
    471   VARIANT Detach();
    472   VARIANT &GetVARIANT() throw();
    473   VARIANT *GetAddress();
    474   void ChangeType(VARTYPE vartype,const _variant_t *pSrc = NULL);
    475   void SetString(const char *pSrc);
    476 };
    477 
    478 inline _variant_t::_variant_t() throw() { ::VariantInit(this); }
    479 inline _variant_t::_variant_t(const VARIANT &varSrc) {
    480   ::VariantInit(this);
    481   _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT*>(&varSrc)));
    482 }
    483 inline _variant_t::_variant_t(const VARIANT *pSrc) {
    484   if(!pSrc) { _com_issue_error(E_POINTER); }
    485   else {
    486     ::VariantInit(this);
    487     _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT*>(pSrc)));
    488   }
    489 }
    490 inline _variant_t::_variant_t(const _variant_t &varSrc) {
    491   ::VariantInit(this);
    492   _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT*>(static_cast<const VARIANT*>(&varSrc))));
    493 }
    494 inline _variant_t::_variant_t(VARIANT &varSrc,bool fCopy) {
    495   if(fCopy) {
    496     ::VariantInit(this);
    497     _com_util::CheckError(::VariantCopy(this,&varSrc));
    498   } else {
    499     _COM_MEMCPY_S(this,sizeof(varSrc),&varSrc,sizeof(varSrc));
    500     V_VT(&varSrc) = VT_EMPTY;
    501   }
    502 }
    503 inline _variant_t::_variant_t(short sSrc,VARTYPE vtSrc) {
    504   if((vtSrc!=VT_I2) && (vtSrc!=VT_BOOL)) {
    505     _com_issue_error(E_INVALIDARG);
    506     return;
    507   }
    508   if(vtSrc==VT_BOOL) {
    509     V_VT(this) = VT_BOOL;
    510     V_BOOL(this) = (sSrc ? VARIANT_TRUE : VARIANT_FALSE);
    511   } else {
    512     V_VT(this) = VT_I2;
    513     V_I2(this) = sSrc;
    514   }
    515 }
    516 inline _variant_t::_variant_t(__LONG32 lSrc,VARTYPE vtSrc) {
    517   if((vtSrc!=VT_I4) && (vtSrc!=VT_ERROR) && (vtSrc!=VT_BOOL)) {
    518     _com_issue_error(E_INVALIDARG);
    519     return;
    520   }
    521   if(vtSrc==VT_ERROR) {
    522     V_VT(this) = VT_ERROR;
    523     V_ERROR(this) = lSrc;
    524   } else if(vtSrc==VT_BOOL) {
    525     V_VT(this) = VT_BOOL;
    526     V_BOOL(this) = (lSrc ? VARIANT_TRUE : VARIANT_FALSE);
    527   } else {
    528     V_VT(this) = VT_I4;
    529     V_I4(this) = lSrc;
    530   }
    531 }
    532 inline _variant_t::_variant_t(float fltSrc) throw() {
    533   V_VT(this) = VT_R4;
    534   V_R4(this) = fltSrc;
    535 }
    536 
    537 inline _variant_t::_variant_t(double dblSrc,VARTYPE vtSrc) {
    538   if((vtSrc!=VT_R8) && (vtSrc!=VT_DATE)) {
    539     _com_issue_error(E_INVALIDARG);
    540     return;
    541   }
    542   if(vtSrc==VT_DATE) {
    543     V_VT(this) = VT_DATE;
    544     V_DATE(this) = dblSrc;
    545   } else {
    546     V_VT(this) = VT_R8;
    547     V_R8(this) = dblSrc;
    548   }
    549 }
    550 inline _variant_t::_variant_t(const CY &cySrc) throw() {
    551   V_VT(this) = VT_CY;
    552   V_CY(this) = cySrc;
    553 }
    554 inline _variant_t::_variant_t(const _bstr_t &bstrSrc) {
    555   V_VT(this) = VT_BSTR;
    556   BSTR bstr = static_cast<wchar_t *>(bstrSrc);
    557   if(!bstr) V_BSTR(this) = NULL;
    558   else {
    559     V_BSTR(this) = ::SysAllocStringByteLen(reinterpret_cast<char *>(bstr),::SysStringByteLen(bstr));
    560     if(!(V_BSTR(this))) { _com_issue_error(E_OUTOFMEMORY); }
    561   }
    562 }
    563 inline _variant_t::_variant_t(const wchar_t *pSrc) {
    564   V_VT(this) = VT_BSTR;
    565   V_BSTR(this) = ::SysAllocString(pSrc);
    566   if(!(V_BSTR(this)) && pSrc!=NULL) { _com_issue_error(E_OUTOFMEMORY); }
    567 }
    568 inline _variant_t::_variant_t(const char *pSrc) {
    569   V_VT(this) = VT_BSTR;
    570   V_BSTR(this) = _com_util::ConvertStringToBSTR(pSrc);
    571 }
    572 inline _variant_t::_variant_t(IDispatch *pSrc,bool fAddRef) throw() {
    573   V_VT(this) = VT_DISPATCH;
    574   V_DISPATCH(this) = pSrc;
    575   if(fAddRef && V_DISPATCH(this)!=NULL) V_DISPATCH(this)->AddRef();
    576 }
    577 inline _variant_t::_variant_t(bool boolSrc) throw() {
    578   V_VT(this) = VT_BOOL;
    579   V_BOOL(this) = (boolSrc ? VARIANT_TRUE : VARIANT_FALSE);
    580 }
    581 inline _variant_t::_variant_t(IUnknown *pSrc,bool fAddRef) throw() {
    582   V_VT(this) = VT_UNKNOWN;
    583   V_UNKNOWN(this) = pSrc;
    584   if(fAddRef && V_UNKNOWN(this)!=NULL) V_UNKNOWN(this)->AddRef();
    585 }
    586 inline _variant_t::_variant_t(const DECIMAL &decSrc) throw() {
    587   V_DECIMAL(this) = decSrc;
    588   V_VT(this) = VT_DECIMAL;
    589 }
    590 inline _variant_t::_variant_t(BYTE bSrc) throw() {
    591   V_VT(this) = VT_UI1;
    592   V_UI1(this) = bSrc;
    593 }
    594 inline _variant_t::_variant_t(char cSrc) throw() {
    595   V_VT(this) = VT_I1;
    596   V_I1(this) = cSrc;
    597 }
    598 inline _variant_t::_variant_t(unsigned short usSrc) throw() {
    599   V_VT(this) = VT_UI2;
    600   V_UI2(this) = usSrc;
    601 }
    602 inline _variant_t::_variant_t(unsigned __LONG32 ulSrc) throw() {
    603   V_VT(this) = VT_UI4;
    604   V_UI4(this) = ulSrc;
    605 }
    606 #ifndef __CYGWIN__
    607 inline _variant_t::_variant_t(int iSrc) throw() {
    608   V_VT(this) = VT_INT;
    609   V_INT(this) = iSrc;
    610 }
    611 inline _variant_t::_variant_t(unsigned int uiSrc) throw() {
    612   V_VT(this) = VT_UINT;
    613   V_UINT(this) = uiSrc;
    614 }
    615 #endif
    616 __MINGW_EXTENSION inline _variant_t::_variant_t(__int64 i8Src) throw() {
    617   V_VT(this) = VT_I8;
    618   V_I8(this) = i8Src;
    619 }
    620 __MINGW_EXTENSION inline _variant_t::_variant_t(unsigned __int64 ui8Src) throw() {
    621   V_VT(this) = VT_UI8;
    622   V_UI8(this) = ui8Src;
    623 }
    624 inline _variant_t::operator short() const {
    625   if(V_VT(this)==VT_I2) return V_I2(this);
    626   _variant_t varDest;
    627   varDest.ChangeType(VT_I2,this);
    628   return V_I2(&varDest);
    629 }
    630 inline _variant_t::operator __LONG32() const {
    631   if(V_VT(this)==VT_I4) return V_I4(this);
    632   _variant_t varDest;
    633   varDest.ChangeType(VT_I4,this);
    634   return V_I4(&varDest);
    635 }
    636 
    637 inline _variant_t::operator float() const {
    638   if(V_VT(this)==VT_R4) return V_R4(this);
    639   _variant_t varDest;
    640   varDest.ChangeType(VT_R4,this);
    641   return V_R4(&varDest);
    642 }
    643 
    644 inline _variant_t::operator double() const {
    645   if(V_VT(this)==VT_R8) return V_R8(this);
    646   _variant_t varDest;
    647   varDest.ChangeType(VT_R8,this);
    648   return V_R8(&varDest);
    649 }
    650 
    651 inline _variant_t::operator CY() const {
    652   if(V_VT(this)==VT_CY) return V_CY(this);
    653   _variant_t varDest;
    654   varDest.ChangeType(VT_CY,this);
    655   return V_CY(&varDest);
    656 }
    657 
    658 inline _variant_t::operator _bstr_t() const {
    659   if(V_VT(this)==VT_BSTR) return V_BSTR(this);
    660   _variant_t varDest;
    661   varDest.ChangeType(VT_BSTR,this);
    662   return V_BSTR(&varDest);
    663 }
    664 
    665 inline _variant_t::operator IDispatch*() const {
    666   if(V_VT(this)==VT_DISPATCH) {
    667     if(V_DISPATCH(this)!=NULL) V_DISPATCH(this)->AddRef();
    668     return V_DISPATCH(this);
    669   }
    670   _variant_t varDest;
    671   varDest.ChangeType(VT_DISPATCH,this);
    672   if(V_DISPATCH(&varDest)!=NULL) V_DISPATCH(&varDest)->AddRef();
    673   return V_DISPATCH(&varDest);
    674 }
    675 inline _variant_t::operator bool() const {
    676   if(V_VT(this)==VT_BOOL) return V_BOOL(this) ? true : false;
    677   _variant_t varDest;
    678   varDest.ChangeType(VT_BOOL,this);
    679   return (V_BOOL(&varDest)==VARIANT_TRUE) ? true : false;
    680 }
    681 
    682 inline _variant_t::operator IUnknown*() const {
    683   if(V_VT(this)==VT_UNKNOWN) {
    684     if(V_UNKNOWN(this)!=NULL) V_UNKNOWN(this)->AddRef();
    685     return V_UNKNOWN(this);
    686   }
    687   _variant_t varDest;
    688   varDest.ChangeType(VT_UNKNOWN,this);
    689   if(V_UNKNOWN(&varDest)!=NULL) V_UNKNOWN(&varDest)->AddRef();
    690   return V_UNKNOWN(&varDest);
    691 }
    692 inline _variant_t::operator DECIMAL() const {
    693   if(V_VT(this)==VT_DECIMAL) return V_DECIMAL(this);
    694   _variant_t varDest;
    695   varDest.ChangeType(VT_DECIMAL,this);
    696   return V_DECIMAL(&varDest);
    697 }
    698 inline _variant_t::operator BYTE() const {
    699   if(V_VT(this)==VT_UI1) return V_UI1(this);
    700   _variant_t varDest;
    701   varDest.ChangeType(VT_UI1,this);
    702   return V_UI1(&varDest);
    703 }
    704 inline _variant_t::operator VARIANT() const throw() { return *(VARIANT*) this; }
    705 inline _variant_t::operator char() const {
    706   if(V_VT(this)==VT_I1) return V_I1(this);
    707   _variant_t varDest;
    708   varDest.ChangeType(VT_I1,this);
    709   return V_I1(&varDest);
    710 }
    711 
    712 inline _variant_t::operator unsigned short() const {
    713   if(V_VT(this)==VT_UI2) return V_UI2(this);
    714   _variant_t varDest;
    715   varDest.ChangeType(VT_UI2,this);
    716   return V_UI2(&varDest);
    717 }
    718 
    719 inline _variant_t::operator unsigned __LONG32() const {
    720   if(V_VT(this)==VT_UI4) return V_UI4(this);
    721   _variant_t varDest;
    722   varDest.ChangeType(VT_UI4,this);
    723   return V_UI4(&varDest);
    724 }
    725 #ifndef __CYGWIN__
    726 inline _variant_t::operator int() const {
    727   if(V_VT(this)==VT_INT) return V_INT(this);
    728   _variant_t varDest;
    729   varDest.ChangeType(VT_INT,this);
    730   return V_INT(&varDest);
    731 }
    732 inline _variant_t::operator unsigned int() const {
    733   if(V_VT(this)==VT_UINT) return V_UINT(this);
    734   _variant_t varDest;
    735   varDest.ChangeType(VT_UINT,this);
    736   return V_UINT(&varDest);
    737 }
    738 #endif
    739 __MINGW_EXTENSION inline _variant_t::operator __int64() const {
    740   if(V_VT(this)==VT_I8) return V_I8(this);
    741   _variant_t varDest;
    742   varDest.ChangeType(VT_I8,this);
    743   return V_I8(&varDest);
    744 }
    745 __MINGW_EXTENSION inline _variant_t::operator unsigned __int64() const {
    746   if(V_VT(this)==VT_UI8) return V_UI8(this);
    747   _variant_t varDest;
    748   varDest.ChangeType(VT_UI8,this);
    749   return V_UI8(&varDest);
    750 }
    751 inline _variant_t &_variant_t::operator=(const VARIANT &varSrc) {
    752   _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT*>(&varSrc)));
    753   return *this;
    754 }
    755 inline _variant_t &_variant_t::operator=(const VARIANT *pSrc) {
    756   if(!pSrc) { _com_issue_error(E_POINTER); }
    757   else { _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT*>(pSrc))); }
    758   return *this;
    759 }
    760 inline _variant_t &_variant_t::operator=(const _variant_t &varSrc) {
    761   _com_util::CheckError(::VariantCopy(this,const_cast<VARIANT*>(static_cast<const VARIANT*>(&varSrc))));
    762   return *this;
    763 }
    764 inline _variant_t &_variant_t::operator=(short sSrc) {
    765   if(V_VT(this)==VT_I2) V_I2(this) = sSrc;
    766   else if(V_VT(this)==VT_BOOL) V_BOOL(this) = (sSrc ? VARIANT_TRUE : VARIANT_FALSE);
    767   else {
    768     Clear();
    769     V_VT(this) = VT_I2;
    770     V_I2(this) = sSrc;
    771   }
    772   return *this;
    773 }
    774 inline _variant_t &_variant_t::operator=(__LONG32 lSrc) {
    775   if(V_VT(this)==VT_I4) V_I4(this) = lSrc;
    776   else if(V_VT(this)==VT_ERROR) V_ERROR(this) = lSrc;
    777   else if(V_VT(this)==VT_BOOL) V_BOOL(this) = (lSrc ? VARIANT_TRUE : VARIANT_FALSE);
    778   else {
    779     Clear();
    780     V_VT(this) = VT_I4;
    781     V_I4(this) = lSrc;
    782   }
    783   return *this;
    784 }
    785 inline _variant_t &_variant_t::operator=(float fltSrc) {
    786   if(V_VT(this)!=VT_R4) {
    787     Clear();
    788     V_VT(this) = VT_R4;
    789   }
    790   V_R4(this) = fltSrc;
    791   return *this;
    792 }
    793 
    794 inline _variant_t &_variant_t::operator=(double dblSrc)
    795 {
    796   if(V_VT(this)==VT_R8) {
    797     V_R8(this) = dblSrc;
    798   }
    799   else if(V_VT(this)==VT_DATE) {
    800     V_DATE(this) = dblSrc;
    801   }
    802   else {
    803 
    804     Clear();
    805 
    806     V_VT(this) = VT_R8;
    807     V_R8(this) = dblSrc;
    808   }
    809 
    810   return *this;
    811 }
    812 
    813 inline _variant_t &_variant_t::operator=(const CY &cySrc)
    814 {
    815   if(V_VT(this)!=VT_CY) {
    816 
    817     Clear();
    818 
    819     V_VT(this) = VT_CY;
    820   }
    821 
    822   V_CY(this) = cySrc;
    823 
    824   return *this;
    825 }
    826 
    827 inline _variant_t &_variant_t::operator=(const _bstr_t &bstrSrc)
    828 {
    829   _COM_ASSERT(V_VT(this)!=VT_BSTR || !((BSTR) bstrSrc) || V_BSTR(this)!=(BSTR) bstrSrc);
    830 
    831   Clear();
    832 
    833   V_VT(this) = VT_BSTR;
    834 
    835   if(!bstrSrc) {
    836     V_BSTR(this) = NULL;
    837   }
    838   else {
    839     BSTR bstr = static_cast<wchar_t *>(bstrSrc);
    840     V_BSTR(this) = ::SysAllocStringByteLen(reinterpret_cast<char *>(bstr),::SysStringByteLen(bstr));
    841 
    842     if(!(V_BSTR(this))) {
    843       _com_issue_error(E_OUTOFMEMORY);
    844     }
    845   }
    846 
    847   return *this;
    848 }
    849 
    850 inline _variant_t &_variant_t::operator=(const wchar_t *pSrc)
    851 {
    852   _COM_ASSERT(V_VT(this)!=VT_BSTR || !pSrc || V_BSTR(this)!=pSrc);
    853 
    854   Clear();
    855 
    856   V_VT(this) = VT_BSTR;
    857 
    858   if(!pSrc) {
    859     V_BSTR(this) = NULL;
    860   }
    861   else {
    862     V_BSTR(this) = ::SysAllocString(pSrc);
    863 
    864     if(!(V_BSTR(this))) {
    865       _com_issue_error(E_OUTOFMEMORY);
    866     }
    867   }
    868 
    869   return *this;
    870 }
    871 
    872 inline _variant_t &_variant_t::operator=(const char *pSrc)
    873 {
    874   _COM_ASSERT(V_VT(this)!=(VT_I1 | VT_BYREF) || !pSrc || V_I1REF(this)!=pSrc);
    875 
    876   Clear();
    877 
    878   V_VT(this) = VT_BSTR;
    879   V_BSTR(this) = _com_util::ConvertStringToBSTR(pSrc);
    880 
    881   return *this;
    882 }
    883 
    884 inline _variant_t &_variant_t::operator=(IDispatch *pSrc)
    885 {
    886   _COM_ASSERT(V_VT(this)!=VT_DISPATCH || pSrc==0 || V_DISPATCH(this)!=pSrc);
    887 
    888   Clear();
    889 
    890   V_VT(this) = VT_DISPATCH;
    891   V_DISPATCH(this) = pSrc;
    892 
    893   if(V_DISPATCH(this)!=NULL) {
    894 
    895     V_DISPATCH(this)->AddRef();
    896   }
    897 
    898   return *this;
    899 }
    900 
    901 inline _variant_t &_variant_t::operator=(bool boolSrc)
    902 {
    903   if(V_VT(this)!=VT_BOOL) {
    904 
    905     Clear();
    906 
    907     V_VT(this) = VT_BOOL;
    908   }
    909 
    910   V_BOOL(this) = (boolSrc ? VARIANT_TRUE : VARIANT_FALSE);
    911 
    912   return *this;
    913 }
    914 
    915 inline _variant_t &_variant_t::operator=(IUnknown *pSrc)
    916 {
    917   _COM_ASSERT(V_VT(this)!=VT_UNKNOWN || !pSrc || V_UNKNOWN(this)!=pSrc);
    918 
    919   Clear();
    920 
    921   V_VT(this) = VT_UNKNOWN;
    922   V_UNKNOWN(this) = pSrc;
    923 
    924   if(V_UNKNOWN(this)!=NULL) {
    925 
    926     V_UNKNOWN(this)->AddRef();
    927   }
    928 
    929   return *this;
    930 }
    931 
    932 inline _variant_t &_variant_t::operator=(const DECIMAL &decSrc)
    933 {
    934   if(V_VT(this)!=VT_DECIMAL) {
    935 
    936     Clear();
    937   }
    938 
    939   V_DECIMAL(this) = decSrc;
    940   V_VT(this) = VT_DECIMAL;
    941 
    942   return *this;
    943 }
    944 
    945 inline _variant_t &_variant_t::operator=(BYTE bSrc)
    946 {
    947   if(V_VT(this)!=VT_UI1) {
    948 
    949     Clear();
    950 
    951     V_VT(this) = VT_UI1;
    952   }
    953 
    954   V_UI1(this) = bSrc;
    955 
    956   return *this;
    957 }
    958 
    959 inline _variant_t &_variant_t::operator=(char cSrc)
    960 {
    961   if(V_VT(this)!=VT_I1) {
    962 
    963     Clear();
    964 
    965     V_VT(this) = VT_I1;
    966   }
    967 
    968   V_I1(this) = cSrc;
    969 
    970   return *this;
    971 }
    972 
    973 inline _variant_t &_variant_t::operator=(unsigned short usSrc)
    974 {
    975   if(V_VT(this)!=VT_UI2) {
    976 
    977     Clear();
    978 
    979     V_VT(this) = VT_UI2;
    980   }
    981 
    982   V_UI2(this) = usSrc;
    983 
    984   return *this;
    985 }
    986 
    987 inline _variant_t &_variant_t::operator=(unsigned __LONG32 ulSrc)
    988 {
    989   if(V_VT(this)!=VT_UI4) {
    990 
    991     Clear();
    992 
    993     V_VT(this) = VT_UI4;
    994   }
    995 
    996   V_UI4(this) = ulSrc;
    997 
    998   return *this;
    999 }
   1000 
   1001 #ifndef __CYGWIN__
   1002 inline _variant_t &_variant_t::operator=(int iSrc)
   1003 {
   1004   if(V_VT(this)!=VT_INT) {
   1005 
   1006     Clear();
   1007 
   1008     V_VT(this) = VT_INT;
   1009   }
   1010 
   1011   V_INT(this) = iSrc;
   1012 
   1013   return *this;
   1014 }
   1015 
   1016 inline _variant_t &_variant_t::operator=(unsigned int uiSrc)
   1017 {
   1018   if(V_VT(this)!=VT_UINT) {
   1019 
   1020     Clear();
   1021 
   1022     V_VT(this) = VT_UINT;
   1023   }
   1024 
   1025   V_UINT(this) = uiSrc;
   1026 
   1027   return *this;
   1028 }
   1029 #endif
   1030 
   1031 __MINGW_EXTENSION inline _variant_t &_variant_t::operator=(__int64 i8Src) {
   1032   if(V_VT(this)!=VT_I8) {
   1033 
   1034     Clear();
   1035 
   1036     V_VT(this) = VT_I8;
   1037   }
   1038 
   1039   V_I8(this) = i8Src;
   1040 
   1041   return *this;
   1042 }
   1043 
   1044 __MINGW_EXTENSION inline _variant_t &_variant_t::operator=(unsigned __int64 ui8Src) {
   1045   if(V_VT(this)!=VT_UI8) {
   1046 
   1047     Clear();
   1048 
   1049     V_VT(this) = VT_UI8;
   1050   }
   1051 
   1052   V_UI8(this) = ui8Src;
   1053 
   1054   return *this;
   1055 }
   1056 
   1057 inline bool _variant_t::operator==(const VARIANT &varSrc) const throw() {
   1058   return *this==&varSrc;
   1059 }
   1060 
   1061 inline bool _variant_t::operator==(const VARIANT *pSrc) const throw()
   1062 {
   1063   if(!pSrc) {
   1064     return false;
   1065   }
   1066 
   1067   if(this==pSrc) {
   1068     return true;
   1069   }
   1070 
   1071   if(V_VT(this)!=V_VT(pSrc)) {
   1072     return false;
   1073   }
   1074 
   1075   switch (V_VT(this)) {
   1076 case VT_EMPTY:
   1077 case VT_NULL:
   1078   return true;
   1079 
   1080 case VT_I2:
   1081   return V_I2(this)==V_I2(pSrc);
   1082 
   1083 case VT_I4:
   1084   return V_I4(this)==V_I4(pSrc);
   1085 
   1086 case VT_R4:
   1087   return V_R4(this)==V_R4(pSrc);
   1088 
   1089 case VT_R8:
   1090   return V_R8(this)==V_R8(pSrc);
   1091 
   1092 case VT_CY:
   1093   return memcmp(&(V_CY(this)),&(V_CY(pSrc)),sizeof(CY))==0;
   1094 
   1095 case VT_DATE:
   1096   return V_DATE(this)==V_DATE(pSrc);
   1097 
   1098 case VT_BSTR:
   1099   return (::SysStringByteLen(V_BSTR(this))==::SysStringByteLen(V_BSTR(pSrc))) &&
   1100     (memcmp(V_BSTR(this),V_BSTR(pSrc),::SysStringByteLen(V_BSTR(this)))==0);
   1101 
   1102 case VT_DISPATCH:
   1103   return V_DISPATCH(this)==V_DISPATCH(pSrc);
   1104 
   1105 case VT_ERROR:
   1106   return V_ERROR(this)==V_ERROR(pSrc);
   1107 
   1108 case VT_BOOL:
   1109   return V_BOOL(this)==V_BOOL(pSrc);
   1110 
   1111 case VT_UNKNOWN:
   1112   return V_UNKNOWN(this)==V_UNKNOWN(pSrc);
   1113 
   1114 case VT_DECIMAL:
   1115   return memcmp(&(V_DECIMAL(this)),&(V_DECIMAL(pSrc)),sizeof(DECIMAL))==0;
   1116 
   1117 case VT_UI1:
   1118   return V_UI1(this)==V_UI1(pSrc);
   1119 
   1120 case VT_I1:
   1121   return V_I1(this)==V_I1(pSrc);
   1122 
   1123 case VT_UI2:
   1124   return V_UI2(this)==V_UI2(pSrc);
   1125 
   1126 case VT_UI4:
   1127   return V_UI4(this)==V_UI4(pSrc);
   1128 
   1129 case VT_INT:
   1130   return V_INT(this)==V_INT(pSrc);
   1131 
   1132 case VT_UINT:
   1133   return V_UINT(this)==V_UINT(pSrc);
   1134 
   1135 case VT_I8:
   1136   return V_I8(this)==V_I8(pSrc);
   1137 
   1138 case VT_UI8:
   1139   return V_UI8(this)==V_UI8(pSrc);
   1140 
   1141 default:
   1142   _com_issue_error(E_INVALIDARG);
   1143 
   1144   }
   1145 
   1146   return false;
   1147 }
   1148 
   1149 inline bool _variant_t::operator!=(const VARIANT &varSrc) const throw()
   1150 {
   1151   return !(*this==&varSrc);
   1152 }
   1153 
   1154 inline bool _variant_t::operator!=(const VARIANT *pSrc) const throw()
   1155 {
   1156   return !(*this==pSrc);
   1157 }
   1158 
   1159 inline void _variant_t::Clear()
   1160 {
   1161   _com_util::CheckError(::VariantClear(this));
   1162 }
   1163 
   1164 inline void _variant_t::Attach(VARIANT &varSrc)
   1165 {
   1166 
   1167   Clear();
   1168 
   1169   _COM_MEMCPY_S(this,sizeof(varSrc),&varSrc,sizeof(varSrc));
   1170   V_VT(&varSrc) = VT_EMPTY;
   1171 }
   1172 
   1173 inline VARIANT _variant_t::Detach()
   1174 {
   1175   VARIANT varResult = *this;
   1176   V_VT(this) = VT_EMPTY;
   1177 
   1178   return varResult;
   1179 }
   1180 
   1181 inline VARIANT &_variant_t::GetVARIANT() throw()
   1182 {
   1183   return *(VARIANT*) this;
   1184 }
   1185 
   1186 inline VARIANT *_variant_t::GetAddress() {
   1187   Clear();
   1188   return (VARIANT*) this;
   1189 }
   1190 inline void _variant_t::ChangeType(VARTYPE vartype,const _variant_t *pSrc) {
   1191   if(!pSrc) pSrc = this;
   1192   if((this!=pSrc) || (vartype!=V_VT(this))) {
   1193     _com_util::CheckError(::VariantChangeType(static_cast<VARIANT*>(this),const_cast<VARIANT*>(static_cast<const VARIANT*>(pSrc)),0,vartype));
   1194   }
   1195 }
   1196 inline void _variant_t::SetString(const char *pSrc) { operator=(pSrc); }
   1197 inline _variant_t::~_variant_t() throw() { ::VariantClear(this); }
   1198 inline _bstr_t::_bstr_t(const _variant_t &var) : m_Data(NULL) {
   1199   if(V_VT(&var)==VT_BSTR) {
   1200     *this = V_BSTR(&var);
   1201     return;
   1202   }
   1203   _variant_t varDest;
   1204   varDest.ChangeType(VT_BSTR,&var);
   1205   *this = V_BSTR(&varDest);
   1206 }
   1207 inline _bstr_t &_bstr_t::operator=(const _variant_t &var) {
   1208   if(V_VT(&var)==VT_BSTR) {
   1209     *this = V_BSTR(&var);
   1210     return *this;
   1211   }
   1212   _variant_t varDest;
   1213   varDest.ChangeType(VT_BSTR,&var);
   1214   *this = V_BSTR(&varDest);
   1215   return *this;
   1216 }
   1217 
   1218 extern _variant_t vtMissing;
   1219 
   1220 #ifndef _USE_RAW
   1221 #define bstr_t _bstr_t
   1222 #define variant_t _variant_t
   1223 #endif
   1224 
   1225 #pragma pop_macro("new")
   1226 
   1227 /* We use _com_issue_error here, but we only provide its inline version in comdef.h,
   1228  * so we need to make sure that it's included as well. */
   1229 #include <comdef.h>
   1230 
   1231 #endif /* __cplusplus */
   1232 
   1233 #endif