📄 variant.hpp
字号:
#endif /* STLSOFT_UNITTEST */
/* /////////////////////////////////////////////////////////////////////////
* Implementation
*/
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
inline void variant::handle_error_(char const* message, HRESULT hr)
{
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
STLSOFT_THROW_X(com_exception(message, hr));
#else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
STLSOFT_SUPPRESS_UNUSED(message);
::VariantClear(this);
this->vt = VT_ERROR;
this->scode = hr;
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
}
inline /* static */ void variant::swap_(VARIANT& lhs, VARIANT& rhs)
{
VARIANT t;
::memcpy(&t, &lhs, sizeof(VARIANT));
::memcpy(&lhs, &rhs, sizeof(VARIANT));
::memcpy(&rhs, &t, sizeof(VARIANT));
}
inline variant::variant()
{
::VariantInit(this);
}
inline variant::variant(class_type const& rhs)
{
::VariantInit(this);
class_type& rhs_ = const_cast<class_type&>(rhs);
HRESULT hr = ::VariantCopy(this, &rhs_);
if(FAILED(hr))
{
handle_error_("failed to copy variant", hr);
}
}
inline variant::variant(VARIANT const& rhs)
{
::VariantInit(this);
HRESULT hr = ::VariantCopy(this, const_cast<VARIANT*>(&rhs));
if(FAILED(hr))
{
handle_error_("failed to copy variant", hr);
}
}
inline variant::class_type &variant::operator =(variant::class_type const& rhs)
{
class_type r(rhs);
r.swap(*this);
return *this;
}
inline variant::variant(bool b)
{
::VariantInit(this);
this->vt = VT_BOOL;
this->boolVal = b ? VARIANT_TRUE : VARIANT_FALSE;
}
inline variant::variant(short i)
{
::VariantInit(this);
this->vt = VT_I2;
this->iVal = i;
}
inline variant::variant(int i)
{
::VariantInit(this);
this->vt = VT_I4;
this->lVal = i;
}
inline variant::variant(long i)
{
::VariantInit(this);
this->vt = VT_I4;
this->lVal = i;
}
inline variant::variant(float r)
{
::VariantInit(this);
this->vt = VT_R4;
this->fltVal = r;
}
inline variant::variant(double r)
{
::VariantInit(this);
this->vt = VT_R8;
this->dblVal = r;
}
inline variant::variant(CY cy)
{
::VariantInit(this);
this->vt = VT_CY;
this->cyVal = cy;
}
inline variant::variant(LPUNKNOWN punk, bool_type bAddRef)
{
::VariantInit(this);
this->vt = VT_UNKNOWN;
this->punkVal = punk;
if( bAddRef &&
NULL != punk)
{
punk->AddRef();
}
}
inline variant::variant(LPDISPATCH pdisp, bool_type bAddRef)
{
::VariantInit(this);
this->vt = VT_DISPATCH;
this->pdispVal = pdisp;
if( bAddRef &&
NULL != pdisp)
{
pdisp->AddRef();
}
}
inline variant::variant(cs_char_a_t const* s, int len /* = -1 */)
{
::VariantInit(this);
this->vt = VT_BSTR;
this->bstrVal = (len < 0) ? bstr_create(s) : bstr_create(s, static_cast<size_type>(len));
if(NULL == this->bstrVal)
{
if( NULL != s &&
'\0' != 0[s])
{
handle_error_("could not initialise from string", E_OUTOFMEMORY);
}
}
}
inline variant::variant(cs_char_w_t const* s, int len /* = -1 */)
{
::VariantInit(this);
this->vt = VT_BSTR;
this->bstrVal = (len < 0) ? bstr_create(s) : bstr_create(s, static_cast<size_type>(len));
if(NULL == this->bstrVal)
{
if( NULL != s &&
'\0' != 0[s])
{
handle_error_("could not initialise from string", E_OUTOFMEMORY);
}
}
}
inline variant::variant(VARIANT const& var, VARTYPE vt)
{
::VariantInit(this);
class_type copy;
HRESULT hr = ::VariantChangeType(©, const_cast<VARIANT*>(&var), 0, vt);
if(FAILED(hr))
{
handle_error_("could not convert variant to requested type", hr);
}
else
{
copy.swap(*this);
}
}
inline void variant::clear()
{
::VariantClear(this);
}
inline HRESULT variant::try_conversion_copy(VARIANT const& var, VARTYPE vt)
{
HRESULT hr;
if(vt == this->vt)
{
hr = S_FALSE;
}
else
{
class_type copy;
hr = ::VariantChangeType(©, const_cast<VARIANT*>(&var), 0, vt);
if(SUCCEEDED(hr))
{
copy.swap(*this);
}
}
return hr;
}
inline HRESULT variant::try_convert(VARTYPE vt)
{
return try_conversion_copy(*this, vt);
}
inline variant::class_type &variant::convert(VARTYPE vt)
{
HRESULT hr = try_convert(vt);
if(FAILED(hr))
{
handle_error_("could not convert variant to requested type", hr);
}
return *this;
}
inline HRESULT variant::QueryInterface(REFIID riid, void **ppv) const
{
COMSTL_ASSERT(NULL != ppv);
if( VT_UNKNOWN == this->vt ||
VT_DISPATCH == this->vt)
{
return (NULL == this->punkVal) ? E_POINTER : this->punkVal->QueryInterface(riid, ppv);
}
return DISP_E_BADVARTYPE;
}
inline void variant::swap(variant::class_type& rhs)
{
swap_(*this, rhs);
}
#if 0
inline variant::bool_type variant::equal(variant::class_type const& rhs) const
{
;
}
inline variant::bool_type variant::equal(VARIANT const& rhs) const
{
;
}
#endif /* 0 */
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
/* ////////////////////////////////////////////////////////////////////// */
#ifndef _COMSTL_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
} // namespace comstl
# else
} // namespace stlsoft::comstl_project
} // namespace stlsoft
# endif /* _STLSOFT_NO_NAMESPACE */
#endif /* !_COMSTL_NO_NAMESPACE */
/* /////////////////////////////////////////////////////////////////////////
* Namespace
*
* The string access shims exist either in the stlsoft namespace, or in the
* global namespace. This is required by the lookup rules.
*
*/
#ifndef _COMSTL_NO_NAMESPACE
# if !defined(_STLSOFT_NO_NAMESPACE) && \
!defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
namespace stlsoft
{
# else /* ? _STLSOFT_NO_NAMESPACE */
/* There is no stlsoft namespace, so must define in the global namespace */
# endif /* !_STLSOFT_NO_NAMESPACE */
# if !defined(_STLSOFT_NO_NAMESPACE) && \
!defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
} // namespace stlsoft
# else /* ? _STLSOFT_NO_NAMESPACE */
/* There is no stlsoft namespace, so must define in the global namespace */
# endif /* !_STLSOFT_NO_NAMESPACE */
#endif /* !_COMSTL_NO_NAMESPACE */
/* ////////////////////////////////////////////////////////////////////// */
#endif /* !COMSTL_INCL_COMSTL_UTIL_HPP_COMSTL_VARIANT */
/* ////////////////////////////////////////////////////////////////////// */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -