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