📄 enumeration_policies.hpp
字号:
static cs_bool_t clone(interface_type *src, interface_type **pdest)
{
COMSTL_ASSERT(NULL != src);
COMSTL_ASSERT(NULL != pdest);
*pdest = share(src);
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
COMSTL_ASSERT(NULL != *pdest);
return true;
#else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
return NULL != *pdest;
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
}
};
/** \brief Policy type that causes COM enumerator cloning according the STL Forward Iterator concept
*
* \ingroup group__library__collections
*
* \param I The enumeration interface
*/
template<ss_typename_param_k I>
struct forward_cloning_policy
: public repeatable_enumerator_tag
{
public:
typedef I interface_type;
typedef interface_type *value_type;
typedef comstl_ns_qual_std(forward_iterator_tag) iterator_tag_type;
public:
/// \brief Gets a working "copy" of the given enumerator root
///
/// \remarks For this policy, this calls Clone(), and throws an
/// instance of comstl::clone_failure if that fails (or returns
/// NULL if exception support is disabled).
static interface_type *get_working_instance(interface_type *root)
{
COMSTL_ASSERT(NULL != root);
interface_type *ret;
HRESULT hr = const_cast<interface_type*>(root)->Clone(&ret);
if(FAILED(hr))
{
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
STLSOFT_THROW_X(clone_failure(hr));
#else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
ret = NULL;
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
}
return ret;
}
/// \brief "Clones" the given COM enumerator interface according to the Forward Iterator concept
static interface_type *share(interface_type *src)
{
COMSTL_ASSERT(NULL != src);
interface_type *ret;
HRESULT hr = const_cast<interface_type*>(src)->Clone(&ret);
if(FAILED(hr))
{
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
STLSOFT_THROW_X(clone_failure(hr));
#else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
ret = NULL;
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
}
return ret;
}
static cs_bool_t clone(interface_type *src, interface_type **pdest)
{
COMSTL_ASSERT(NULL != src);
COMSTL_ASSERT(NULL != pdest);
*pdest = share(src);
#ifdef STLSOFT_CF_EXCEPTION_SUPPORT
COMSTL_ASSERT(NULL != *pdest);
return true;
#else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
return NULL != *pdest;
#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
}
};
/** \brief Adapts a value policy to a function class based interface
*
* \ingroup group__library__collections
*
* \param P The value policy (e.g. BSTR_policy, VARIANT_policy, FORMATETC_policy)
*/
template <ss_typename_param_k P>
struct value_policy_adaptor
: public P
{
public:
typedef ss_typename_type_k P::value_type value_type;
public:
/// \brief The initialisation function class
struct init_element
{
/// The function call operator, which causes the value to be initialised
void operator ()(value_type &v) const
{
P::init(&v);
}
};
/// \brief The copy function class
struct copy_element
{
/// The function call operator, which causes the destination to be copied from the source
void operator ()(value_type &dest, value_type const& src) const
{
P::copy(&dest, &src);
}
};
/// \brief The clear function class
struct clear_element
{
/// The function call operator, which causes the value to be cleared
void operator ()(value_type &v) const
{
P::clear(&v);
}
};
};
/** \brief [DEPRECATED] Adapts a value policy to a function class based interface
*
* \deprecated Equivalent to value_policy_adaptor
*
* \ingroup group__library__collections
*/
template <ss_typename_param_k P>
struct policy_adaptor
: public value_policy_adaptor<P>
{
public:
typedef ss_typename_type_k P::value_type value_type;
};
/** \brief Acquires an enumerator from a collection assuming _NewEnum property
*
* \ingroup group__library__collections
*
* \remarks Invokes the the get__NewEnum() method
*/
template <ss_typename_param_k CI>
struct new_enum_property_policy
{
public:
typedef CI collection_interface;
public:
static HRESULT acquire(collection_interface *pcoll, LPUNKNOWN *ppunkEnum)
{
COMSTL_ASSERT(NULL != pcoll);
COMSTL_ASSERT(NULL != ppunkEnum);
// If the compiler complains here that your interface does not have the
// get__NewEnum method, then:
//
// - you're passing a pure IDispatch interface, so you need to use
// new_enum_by_dispid_policy
// - you're passing a collection interface that defines _NeWEnum as a
// method, so you need to use new_enum_method_policy
// - you're passing the wrong interface. Check your code to ensure
// you've not used the wrong interface to specialise
// comstl::collection_sequence.
return pcoll->get__NewEnum(ppunkEnum);
}
};
/** \brief Acquires an enumerator from a collection assuming _NewEnum method
*
* \ingroup group__library__collections
*
* \remarks Invokes the the _NewEnum() method
*/
template <ss_typename_param_k CI>
struct new_enum_method_policy
{
public:
typedef CI collection_interface;
public:
static HRESULT acquire(collection_interface *pcoll, LPUNKNOWN *ppunkEnum)
{
COMSTL_ASSERT(NULL != pcoll);
COMSTL_ASSERT(NULL != ppunkEnum);
return pcoll->_NewEnum(ppunkEnum);
}
};
/** \brief Acquires an enumerator from a collection by looking up the DISPID_NEWENUM on the collection's IDispatch interface
*
* \ingroup group__library__collections
*
* \remarks Calls IDispatch::Invoke(DISPID_NEWENUM, . . . , DISPATCH_METHOD | DISPATCH_PROPERTYGET, . . . );
*/
template <ss_typename_param_k CI>
struct new_enum_by_dispid_policy
{
public:
typedef CI collection_interface;
public:
static HRESULT acquire(collection_interface *pcoll, LPUNKNOWN *ppunkEnum)
{
COMSTL_ASSERT(NULL != pcoll);
COMSTL_ASSERT(NULL != ppunkEnum);
LPDISPATCH pdisp;
HRESULT hr = pcoll->QueryInterface(IID_IDispatch, reinterpret_cast<void**>(&pdisp));
if(SUCCEEDED(hr))
{
DISPPARAMS params;
UINT argErrIndex;
VARIANT result;
::memset(¶ms, 0, sizeof(params));
::VariantInit(&result);
hr = pdisp->Invoke( DISPID_NEWENUM
, IID_NULL
, LOCALE_USER_DEFAULT
, DISPATCH_METHOD | DISPATCH_PROPERTYGET
, ¶ms
, &result
, NULL
, &argErrIndex);
pdisp->Release();
if(SUCCEEDED(hr))
{
hr = ::VariantChangeType(&result, &result, 0, VT_UNKNOWN);
if(SUCCEEDED(hr))
{
if(NULL == result.punkVal)
{
hr = E_UNEXPECTED;
}
else
{
*ppunkEnum = result.punkVal;
(*ppunkEnum)->AddRef();
}
}
::VariantClear(&result);
}
}
return hr;
}
};
/* ////////////////////////////////////////////////////////////////////// */
#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 */
/* ////////////////////////////////////////////////////////////////////// */
#endif /* !COMSTL_INCL_COMSTL_COLLECTIONS_HPP_ENUMERATION_POLICIES */
/* ////////////////////////////////////////////////////////////////////// */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -