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