⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 interface_cast.hpp

📁 新版本TR1的stl
💻 HPP
📖 第 1 页 / 共 3 页
字号:
}
\endcode
 */
template<   ss_typename_param_k IDest
        ,   ss_typename_param_k ISrc
        >
#if defined(STLSOFT_COMPILER_IS_MSVC) && \
    _MSC_VER < 1300
// This workaround is required to stop the poor dear from instantiating
// interface_cast_tester on ISrc rather than IDest.
inline cs_bool_t interface_cast_test(ISrc *src, IDest * = NULL)
#else /* ? compiler */
inline cs_bool_t interface_cast_test(ISrc *src)
#endif /* compiler */
{
    interface_cast_tester<IDest>    b(src);

    return !!b;
}

/** \brief Determines whether an interface is available on an object
 *
 * \ingroup group__library__conversion
 *
\code
stlsoft::ref_ptr<IStream>   stm = . . .

if(comstl::interface_cast_test<IStorage>(stm))
{
  printf("Wrapper object has IStorage interface\n");
}
else
{
  printf("Wrapper object does not have IStorage interface\n");
}
\endcode
 *
 * \param src wrapper instance holding the object whose capabilities
 *   will be tested. May be empty.
 */
template<   ss_typename_param_k IDest
        ,   ss_typename_param_k ISrc
        >
#if defined(STLSOFT_COMPILER_IS_MSVC) && \
    _MSC_VER < 1300
// This workaround is required to stop the poor dear from instantiating
// interface_cast_tester on ISrc rather than IDest.
inline cs_bool_t interface_cast_test(stlsoft_ns_qual(ref_ptr)<ISrc> &src, IDest * = NULL)
#else /* ? compiler */
inline cs_bool_t interface_cast_test(stlsoft_ns_qual(ref_ptr)<ISrc> &src)
#endif /* compiler */
{
    return interface_cast_test<IDest*>(src.get());
}


#ifdef STLSOFT_CF_EXCEPTION_SUPPORT

/** \brief Casts a raw interface pointer to a wrapped instance.
 *
 * \ingroup group__library__conversion
 *
\code
IStream   *stm = . . .

try
{
  stlsoft::ref_ptr<IStorage>  stg = comstl::interface_cast<IStorage>(stm);

  printf("Object has IStorage interface\n");
}
catch(comstl::bad_interface_cast &)
{
  printf("Object does not have IStorage interface\n");
}
\endcode
 *
 * \note For technical reasons, the cast destination type differs from the
 *   conventional behaviour. Rather than specifying the actual resultant
 *   type, e.g. <code>stlsoft::ref_ptr<IStream></code>, just the destination
 *   interface type must be specified, e.g.
 *   <code>interface_cast<IStream></code>.
 *
 * \exception comstl::bad_interface_cast When compiling with exception - 
 *   detected when <code>STLSOFT_CF_EXCEPTION_SUPPORT</code> is defined -
 *   this will throw an instance of comstl::bad_interface_cast if the
 *   requested interface cannot be acquired. When compiling absent exception
 *   support, this cast function is not defined; instead use
 *   comstl::try_interface_cast.
 */
template<   ss_typename_param_k IDest
        ,   ss_typename_param_k ISrc
        >
inline stlsoft_ns_qual(ref_ptr)<IDest> interface_cast(ISrc *src)
{
    interface_cast_addref<IDest*, throw_bad_interface_cast_exception> ptr(src);   // This has to be separate, otherwise G++ has a spit

    return stlsoft_ns_qual(ref_ptr)<IDest>(static_cast<IDest*>(ptr), true);
}

/** \brief Casts between instances of wrapped instances
 *
 * \ingroup group__library__conversion
 *
\code
stlsoft::ref_ptr<IStream>   stm = . . .

try
{
  stlsoft::ref_ptr<IStorage>  stg = comstl::interface_cast<IStorage>(stm);

  printf("Wrapper object has IStorage interface\n");
}
catch(comstl::bad_interface_cast &)
{
  printf("Wrapper object does not have IStorage interface\n");
}
\endcode
 *
 * \note For technical reasons, the cast destination type differs from the
 *   conventional behaviour. Rather than specifying the actual resultant
 *   type, e.g. <code>stlsoft::ref_ptr<IStream></code>, just the destination
 *   interface type must be specified, e.g.
 *   <code>interface_cast<IStream></code>.
 *
 * \exception comstl::bad_interface_cast When compiling with exception - 
 *   detected when <code>STLSOFT_CF_EXCEPTION_SUPPORT</code> is defined -
 *   this will throw an instance of comstl::bad_interface_cast if the
 *   requested interface cannot be acquired. When compiling absent exception
 *   support, this cast function is not defined; instead use
 *   comstl::try_interface_cast.
 */
template<   ss_typename_param_k IDest
        ,   ss_typename_param_k ISrc
        >
inline stlsoft_ns_qual(ref_ptr)<IDest> interface_cast(stlsoft_ns_qual(ref_ptr)<ISrc> src)
{
    return interface_cast<IDest>(src.get());
}

#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */


/** \brief Attempts to cast a raw interface pointer to a wrapped instance.
 *
 * \ingroup group__library__conversion
 *
\code
IStream                     *pstm = . . . 
stlsoft::ref_ptr<IStorage>  stg   = comstl::interface_cast<IStorage>(pstm);

if(!stg.empty())
{
  . . . // use stg->
}
\endcode
 *
 * \note For technical reasons, the cast destination type differs from the
 *   conventional behaviour. Rather than specifying the actual resultant
 *   type, e.g. <code>stlsoft::ref_ptr<IStream></code>, just the destination
 *   interface type must be specified, e.g.
 *   <code>interface_cast<IStream></code>.
 *
 * \return 
 */
template<   ss_typename_param_k IDest
        ,   ss_typename_param_k ISrc
        >
inline stlsoft_ns_qual(ref_ptr)<IDest> try_interface_cast(ISrc *src)
{
    interface_cast_addref<IDest*>   ptr(src);  // This has to be separate, otherwise G++ has a spit

    return stlsoft_ns_qual(ref_ptr)<IDest>(static_cast<IDest*>(ptr), true);
}

/** \brief Attempts to cast between instances of wrapped instances
 *
 * \ingroup group__library__conversion
 *
 * \note For technical reasons, the cast destination type differs from the
 *   conventional behaviour. Rather than specifying the actual resultant
 *   type, e.g. <code>stlsoft::ref_ptr<IStream></code>, just the destination
 *   interface type must be specified, e.g.
 *   <code>interface_cast<IStream></code>.
 */
template<   ss_typename_param_k IDest
        ,   ss_typename_param_k ISrc
        >
inline stlsoft_ns_qual(ref_ptr)<IDest> try_interface_cast(stlsoft_ns_qual(ref_ptr)<ISrc> src)
{
    return try_interface_cast<IDest>(src.get());
}

/* /////////////////////////////////////////////////////////////////////////
 * Shims
 */

#ifdef STLSOFT_CF_EXCEPTION_SUPPORT

# if !defined(STLSOFT_COMPILER_IS_COMO) && \
     !defined(STLSOFT_COMPILER_IS_GCC)

/** \brief Attribute shim to retrieve the interface pointer of the given cast instance
 *
 * \ingroup group__concept__shim__pointer_attribute__get_ptr
 *
 * \param p The cast instance
 */
template<   ss_typename_param_k I
        ,   ss_typename_param_k X
        >
inline I get_ptr(comstl_ns_qual(interface_cast_noaddref)<I, X> &p)
{
    return p.operator -> ();
}
# endif /* compiler */

/** \brief Attribute shim to retrieve the interface pointer of the given cast instance
 *
 * \ingroup group__concept__shim__pointer_attribute__get_ptr
 *
 * \param p The cast instance
 */
template<   ss_typename_param_k I
        ,   ss_typename_param_k X
        >
inline I get_ptr(comstl_ns_qual(interface_cast_noaddref)<I, X> const& p)
{
    return p.operator -> ();
}

#endif /* STLSOFT_CF_EXCEPTION_SUPPORT */

/** \brief Attribute shim to retrieve the interface pointer of the given cast instance
 *
 * \ingroup group__concept__shim__pointer_attribute__get_ptr
 *
 * \param p The cast instance
 */
template<   ss_typename_param_k I
        ,   ss_typename_param_k X
        >
inline I get_ptr(comstl_ns_qual(interface_cast_addref)<I, X> &p)
{
    return p;
}

/** \brief Attribute shim to retrieve the interface pointer of the given cast instance
 *
 * \ingroup group__concept__shim__pointer_attribute__get_ptr
 *
 * \param p The cast instance
 */
template<   ss_typename_param_k I
        ,   ss_typename_param_k X
        >
inline I const get_ptr(comstl_ns_qual(interface_cast_addref)<I, X> const& p)
{
    return p;
}

/* /////////////////////////////////////////////////////////////////////////
 * Deprecated Shims
 */

#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION

# ifdef STLSOFT_CF_EXCEPTION_SUPPORT

template<   ss_typename_param_k I
        ,   ss_typename_param_k X
        >
inline cs_bool_t is_empty(comstl_ns_qual(interface_cast_noaddref)<I, X> const& p)
{
    return NULL != get_ptr(p);
}

# endif /* STLSOFT_CF_EXCEPTION_SUPPORT */

template<   ss_typename_param_k I
        ,   ss_typename_param_k X
        >
inline cs_bool_t is_empty(comstl_ns_qual(interface_cast_addref)<I, X> const& p)
{
    return NULL != get_ptr(p);
}

#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */

////////////////////////////////////////////////////////////////////////////
// Unit-testing

#ifdef STLSOFT_UNITTEST
# include "./unittest/interface_cast_unittest_.h"
#endif /* STLSOFT_UNITTEST */

/* ////////////////////////////////////////////////////////////////////// */

#ifndef _COMSTL_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
     defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
} // namespace comstl
# else
} // namespace 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 */

using ::comstl::get_ptr;

#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION

using ::comstl::is_empty;

#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */

# 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_CONVERSION_HPP_INTERFACE_CAST */

/* ////////////////////////////////////////////////////////////////////// */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -