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

📄 scoped_handle.hpp

📁 新版本TR1的stl
💻 HPP
📖 第 1 页 / 共 3 页
字号:

        STLSOFT_MESSAGE_ASSERT("function pointer must not be NULL", NULL != fn);

        fn();
    }
};
# endif /* STLSOFT_CF_STDCALL_SUPPORTED */




#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */


/** \brief Provides automated scope-based cleanup of arbitrary resource
 *    types without any memory allocation required to implement the generic
 *    support.
 *
 * \ingroup group__library__smart_pointers
 *
 * The template is parameterised on the resource type (e.g. FILE*, int, void*)
 * and instances are initialised from a resource handle and the address of a
 * (single-parameter) cleanup function, as in:
 *
\code
 ::stlsoft::scoped_handle<void*>  h3(::malloc(100), ::free);
\endcode
 *
 * or:
 *
\code
 ::stlsoft::scoped_handle<int>    h1(::open("file.ext"), ::close);
\endcode
 *
 * or:
 *
\code
 FILE                             *file = ::fopen("file.ext", "r");
 ::stlsoft::scoped_handle<FILE*>  h2(file, ::fclose);
\endcode
 *
 * \note This class provides externally-initialised immutable-RAII (see section
 * 3.5 of Imperfect C++; http://imperfectcplusplus.com/). The managed resource
 * must be provided in the constructor, and the managing instance cannot be set
 * to manage another resource. However, there is a nod to convenience in so far
 * as there is a detach() method, which can be used to clear the resource from
 * the managing instance and return it to the calling context.
 */

template<ss_typename_param_k H>
class scoped_handle
{
/// \name Types
/// @{
private:
    typedef void (STLSOFT_CDECL *degenerate_function_type)();
    typedef H_holder<H>         holder_type;
public:
    /// \brief The resource type
    typedef H                   resource_type;
    /// \brief The handle type
    typedef H                   handle_type;
    /// \brief The instantiation of the type
    typedef scoped_handle<H>    class_type;
/// @}

/// \name Construction
/// @{
public:
#ifdef STLSOFT_CF_CDECL_SUPPORTED
# if !defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT) || \
     defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_OVERLOAD_DISCRIMINATED)
    /// \brief Construct from a resource handle and a clean-up function with void return type
    scoped_handle(  resource_type   h
                ,   void            (STLSOFT_CDECL *f)(resource_type)
                ,   resource_type   hNull = 0)
        : m_hh(h)
        , m_hNull(hNull)
        , m_tfn(&function_translator_cdecl<H, void>::translate)
        , m_fn(reinterpret_cast<degenerate_function_type>(f))
    {
        STLSOFT_MESSAGE_ASSERT("Precondition violation: cannot initialise with a NULL function pointer", NULL != f);
    }

    /// \brief Construct from a resource handle and an indirect clean-up function with void return type
    scoped_handle(  resource_type   *ph
                ,   void            (STLSOFT_CDECL *f)(resource_type*)
                ,   resource_type   hNull = 0)
        : m_hh(ph)
        , m_hNull(hNull)
        , m_tfn(&function_translator_cdecl<H, void>::translate_indirect)
        , m_fn(reinterpret_cast<degenerate_function_type>(f))
    {
        STLSOFT_MESSAGE_ASSERT("Precondition violation: cannot initialise with a NULL function pointer", NULL != f);
    }
# endif /* !STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT || STLSOFT_CF_MEMBER_TEMPLATE_CTOR_OVERLOAD_DISCRIMINATED */

# if defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT)
    /// \brief Construct from a resource handle and a clean-up function with non-void return type
    template <ss_typename_param_k R>
    scoped_handle(  resource_type   h
                ,   R               (STLSOFT_CDECL *f)(resource_type)
                ,   resource_type   hNull = 0)
        : m_hh(h)
        , m_hNull(hNull)
        , m_tfn(&function_translator_cdecl<H, R>::translate)
        , m_fn(reinterpret_cast<degenerate_function_type>(f))
    {
        STLSOFT_MESSAGE_ASSERT("Precondition violation: cannot initialise with a NULL function pointer", NULL != f);
    }
    /// \brief Construct from a resource handle and an indirect clean-up function with non-void return type
    template <ss_typename_param_k R>
    scoped_handle(  resource_type   *ph
                ,   R               (STLSOFT_CDECL *f)(resource_type*)
                ,   resource_type   hNull = 0)
        : m_hh(ph)
        , m_hNull(hNull)
        , m_tfn(&function_translator_cdecl<H, R>::translate_indirect)
        , m_fn(reinterpret_cast<degenerate_function_type>(f))
    {
        STLSOFT_MESSAGE_ASSERT("Precondition violation: cannot initialise with a NULL function pointer", NULL != f);
    }
# endif /* STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT */
#endif /* STLSOFT_CF_CDECL_SUPPORTED */

#ifdef STLSOFT_CF_FASTCALL_SUPPORTED
# if !defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT) || \
     defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_OVERLOAD_DISCRIMINATED)
    /// \brief Construct from a resource handle and a clean-up "fastcall" function with void return type
    scoped_handle(  resource_type   h
                ,   void            (STLSOFT_FASTCALL *f)(resource_type)
                ,   resource_type   hNull = 0)
        : m_hh(h)
        , m_hNull(hNull)
        , m_tfn(&function_translator_fastcall<H, void>::translate)
        , m_fn(reinterpret_cast<degenerate_function_type>(f))
    {
        STLSOFT_MESSAGE_ASSERT("Precondition violation: cannot initialise with a NULL function pointer", NULL != f);
    }
    /// \brief Construct from a resource handle and an indirect clean-up "fastcall" function with void return type
    scoped_handle(  resource_type   h
                ,   void            (STLSOFT_FASTCALL *f)(resource_type *)
                ,   resource_type   hNull = 0)
        : m_hh(h)
        , m_hNull(hNull)
        , m_tfn(&function_translator_fastcall<H, void>::translate_indirect)
        , m_fn(reinterpret_cast<degenerate_function_type>(f))
    {
        STLSOFT_MESSAGE_ASSERT("Precondition violation: cannot initialise with a NULL function pointer", NULL != f);
    }
# endif /* !STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT || STLSOFT_CF_MEMBER_TEMPLATE_CTOR_OVERLOAD_DISCRIMINATED */

# if defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT)
    /// \brief Construct from a resource handle and a clean-up "fastcall" function with non-void return type
    template <ss_typename_param_k R>
    scoped_handle(  resource_type   h
                ,   R               (STLSOFT_FASTCALL *f)(resource_type)
                ,   resource_type   hNull = 0)
        : m_hh(h)
        , m_hNull(hNull)
        , m_tfn(&function_translator_fastcall<H, R>::translate)
        , m_fn(reinterpret_cast<degenerate_function_type>(f))
    {
        STLSOFT_MESSAGE_ASSERT("Precondition violation: cannot initialise with a NULL function pointer", NULL != f);
    }
    /// \brief Construct from a resource handle and an indirect clean-up "fastcall" function with non-void return type
    template <ss_typename_param_k R>
    scoped_handle(  resource_type   *ph
                ,   R               (STLSOFT_FASTCALL *f)(resource_type*)
                ,   resource_type   hNull = 0)
        : m_hh(ph)
        , m_hNull(hNull)
        , m_tfn(&function_translator_fastcall<H, R>::translate_indirect)
        , m_fn(reinterpret_cast<degenerate_function_type>(f))
    {
        STLSOFT_MESSAGE_ASSERT("Precondition violation: cannot initialise with a NULL function pointer", NULL != f);
    }
# endif /* STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT */
#endif /* STLSOFT_CF_FASTCALL_SUPPORTED */


#ifdef STLSOFT_CF_STDCALL_SUPPORTED
# if !defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT) || \
     defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_OVERLOAD_DISCRIMINATED)
    /// \brief Construct from a resource handle and a clean-up "stdcall" function with void return type
    scoped_handle(  resource_type   h
                ,   void            (STLSOFT_STDCALL *f)(resource_type)
                ,   resource_type   hNull = 0)
        : m_hh(h)
        , m_hNull(hNull)
        , m_tfn(&function_translator_stdcall<H, void>::translate)
        , m_fn(reinterpret_cast<degenerate_function_type>(f))
    {
        STLSOFT_MESSAGE_ASSERT("Precondition violation: cannot initialise with a NULL function pointer", NULL != f);
    }
    /// \brief Construct from a resource handle and an indirect clean-up "stdcall" function with void return type
    scoped_handle(  resource_type   *ph
                ,   void            (STLSOFT_STDCALL *f)(resource_type*)
                ,   resource_type   hNull = 0)
        : m_hh(ph)
        , m_hNull(hNull)
        , m_tfn(&function_translator_stdcall<H, void>::translate_indirect)
        , m_fn(reinterpret_cast<degenerate_function_type>(f))
    {
        STLSOFT_MESSAGE_ASSERT("Precondition violation: cannot initialise with a NULL function pointer", NULL != f);
    }
# endif /* !STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT || STLSOFT_CF_MEMBER_TEMPLATE_CTOR_OVERLOAD_DISCRIMINATED */

# if defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT)
    /// \brief Construct from a resource handle and a clean-up "stdcall" function with non-void return type
    template <ss_typename_param_k R>
    scoped_handle(  resource_type   h
                ,   R               (STLSOFT_STDCALL *f)(resource_type)
                ,   resource_type   hNull = 0)
        : m_hh(h)
        , m_hNull(hNull)
        , m_tfn(&function_translator_stdcall<H, R>::translate)
        , m_fn(reinterpret_cast<degenerate_function_type>(f))
    {
        STLSOFT_MESSAGE_ASSERT("Precondition violation: cannot initialise with a NULL function pointer", NULL != f);
    }
    /// \brief Construct from a resource handle and an indirect clean-up "stdcall" function with non-void return type
    template <ss_typename_param_k R>
    scoped_handle(  resource_type   *ph
                ,   R               (STLSOFT_STDCALL *f)(resource_type*)
                ,   resource_type   hNull = 0)
        : m_hh(ph)
        , m_hNull(hNull)
        , m_tfn(&function_translator_stdcall<H, R>::translate_indirect)
        , m_fn(reinterpret_cast<degenerate_function_type>(f))
    {
        STLSOFT_MESSAGE_ASSERT("Precondition violation: cannot initialise with a NULL function pointer", NULL != f);
    }
# endif /* STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT */
#endif /* STLSOFT_CF_STDCALL_SUPPORTED */

    /// \brief "Releases" the managed resource.
    ///
    /// Invokes the cleanup function, unless close() or detach() have
    /// already been called
    ~scoped_handle()
    {
        STLSOFT_MESSAGE_ASSERT("Invariant violation: function pointer must not be NULL", NULL != m_fn);

        if(!empty())
        {
            m_tfn(m_hh, m_fn);
        }
    }
/// @}

/// \name Attributes
/// @{
public:
    /// \brief Indicates whether the instance holds a non-"null" resource
    bool empty() const
    {
        STLSOFT_MESSAGE_ASSERT("Invariant violation: function pointer must not be NULL", NULL != m_fn);

        return get_null_value_() == m_hh.get();
    }
/// @}

/// \name Operations
/// @{
public:
    /// \brief Closes the handle immediately
    ///
    /// \note Calling this method more than once has no effect.
    void close()
    {
        STLSOFT_MESSAGE_ASSERT("Invariant violation: function pointer must not be NULL", NULL != m_fn);

        if(!empty())
        {
            m_tfn(m_hh, m_fn);

            m_hh.set(get_null_value_());
        }
    }

    /// \brief Detaches the resource, and returns it to the caller.
    ///
    /// \remarks Calling this method removes the resource from the managing
    ///   instance, so it will not be automatically closed.
    resource_type detach()
    {
        STLSOFT_MESSAGE_ASSERT("Invariant violation: function pointer must not be NULL", NULL != m_fn);

        resource_type   h   =   m_hh.get();

        m_hh.set(get_null_value_());

        return h;
    }
/// @}

/// \name Accessors
/// @{
public:
    /// \brief Provides the bare resource handle to the caller. Does not
    ///   detach the handle from the managing instance.

⌨️ 快捷键说明

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