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

📄 method_properties.hpp

📁 新版本TR1的stl
💻 HPP
📖 第 1 页 / 共 4 页
字号:
                                                    ,   &C::SM              \
                                                    >       P

#define STLSOFT_METHOD_PROPERTY_GETSET_EXTERNAL(RG, RS, C, GM, SM, P)   \
                                                                        \
    STLSOFT_METHOD_PROPERTY_DEFINE_OFFSET(C, P)                         \
    STLSOFT_METHOD_PROPERTY_GETSET_EXTERNAL_PROP(RG, RS, C, GM, SM, P)

#else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */

#endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */


/* /////////////////////////////////////////////////////////////////////////
 * Classes
 */

struct property_tag
{};

struct internal_property_tag
    : public property_tag
{
    enum { is_internal  =   1       };
    enum { is_external  =   0       };
};

struct external_property_tag
    : public property_tag
{
    enum { is_internal  =   0       };
    enum { is_external  =   1       };
};

template<   int R
        ,   int W
        ,   int S
        >
struct internal_property
    : public internal_property_tag
{
    enum { is_read      =   R       };
    enum { is_write     =   W       };
    enum { is_static    =   S       };
};

template<   int R
        ,   int W
        ,   int S
        >
struct external_property
    : public external_property_tag
{
    enum { is_read      =   R       };
    enum { is_write     =   W       };
    enum { is_static    =   S       };
};

/* /////////////////////////////////////////////////////////////////////////
 * Internal method property classes
 */

// Some compilers store member functions as very large quantities, e.g Borland
// uses 12-bytes on Win32, so the pointer to member is stored in a static method
// of a unique type, whose users are required to call its constructor before
// accessing its static method

/** \brief Provides static storage and access to a get member function of a
 *   given type.
 *
 * \ingroup group__library__properties
 */
template<   ss_typename_param_k T /* The outer class, used to provide uniqueness */
        ,   ss_typename_param_k R   /* The reference type */
        ,   ss_typename_param_k C   /* The enclosing class */
        >
struct member_get_pointer
{
private:
    member_get_pointer(R (C::*pfn)() const)
    {
        function(pfn, NULL, NULL);
    }

    STLSOFT_DECLARE_TEMPLATE_PARAM_AS_FRIEND(T);

    static R get(C *pC)
    {
        R   r;

        function(NULL, pC, &r);

        return r;
    }

private:
    static void function(R (C::*pfn)() const , C *pC, R *pR)
    {
        static R (C::*s_pfn)() const    =   pfn;

        STLSOFT_MESSAGE_ASSERT("member_get_pointer called before being initialised!", NULL != s_pfn);

        if(NULL != pC)
        {
            *pR = (pC->*s_pfn)();
        }
    }
};


/** \brief Provides static storage and access to a set member function of a
 *   given type.
 *
 * \ingroup group__library__properties
 */
template<   ss_typename_param_k T /* The outer class, used to provide uniqueness */
        ,   ss_typename_param_k R   /* The reference type */
        ,   ss_typename_param_k C   /* The enclosing class */
        >
struct member_set_pointer
{
private:
    member_set_pointer(void (C::*pfn)(R ))
    {
        function(pfn, NULL, NULL);
    }

    STLSOFT_DECLARE_TEMPLATE_PARAM_AS_FRIEND(T);

    static void set(C *pC, R *pR)
    {
        function(NULL, pC, pR);
    }

private:
    static void function(void (C::*pfn)(R ) , C *pC, R *pR)
    {
        static void (C::*s_pfn)(R ) =   pfn;

        STLSOFT_MESSAGE_ASSERT("member_set_pointer called before being initialised!", NULL != s_pfn);

        if(NULL != pC)
        {
            (pC->*s_pfn)(*pR);
        }
    }
};

/** \brief This class provides method-based read-only property access
 *
 * \ingroup group__library__properties
 *
 * The containing class defines a get method. It also defines a static method
 * that contains the offset of the given property from within the container.
 * Then the template is parameterised with the value type, the reference type,
 * the container type, the member function and the offset function.
 */
template<   ss_typename_param_k V       /* The actual property value type */
        ,   ss_typename_param_k R       /* The reference type */
        ,   ss_typename_param_k C       /* The enclosing class */
        ,   ss_ptrdiff_t (*PFnOff)()    /* Pointer to function providing offset of property within container */
#ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
        ,   R (C::*PFnGet)() const  /* Pointer to a const member function returning R */
#endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
        >
class method_property_get
    : public internal_property<1, 0, 0>
{
/// \name Member Types
/// @{
public:
    typedef V                                               value_type;
    typedef R                                               reference_type;
    typedef C                                               container_type;
#ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
    typedef method_property_get<V, R, C, PFnOff, PFnGet>    class_type;
#else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
    typedef method_property_get<V, R, C, PFnOff>            class_type;
    typedef member_get_pointer<class_type, R, C>            member_pointer_type;
#endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */

# if defined(STLSOFT_COMPILER_IS_DMC)
/// @}

/// \name Construction
/// @{
public:
# else
private:
# endif /* compiler */
    method_property_get()
    {}
private:
    ss_explicit_k method_property_get(reference_type value)
        : m_value(value)
    {}

#ifndef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
private:
    typedef member_pointer_type PFnGet;

private:
    method_property_get(reference_type (C::*pfn)() const)
    {
        PFnGet  f(pfn);
    }
#endif /* !STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */

    STLSOFT_DECLARE_TEMPLATE_PARAM_AS_FRIEND(C);
/// @}

/// \name Accessors
/// @{
public:
    /// Provides read-only access to the property
    operator reference_type() const
    {
        ss_ptrdiff_t    offset  =   (*PFnOff)();
        container_type  *pC     =   (container_type*)((ss_byte_t*)this - offset);

#ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
        return (pC->*PFnGet)();
#else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
        return PFnGet::get(pC);
#endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
    }
/// @}

/// \name Members
/// @{
private:
    value_type  m_value;
/// @}

/// \name Not to be implemented
/// @{
private:
    /// This method is hidden in order to prevent users of this class from
    /// becoming familiar with using operator = on the property instances
    /// from within the containing class, since doing so with
    /// method_property_getset<> would result in an infinite loop.
    class_type& operator =(reference_type value);
/// @}
};


/** \brief This class provides method-based write-only property access
 *
 * \ingroup group__library__properties
 *
 * The containing class defines a set method. It also defines a static method
 * that contains the offset of the given property from within the container.
 * Then the template is parameterised with the value type, the reference type,
 * the container type, the member function and the offset function.
 */
template<   ss_typename_param_k V       /* The actual property value type */
        ,   ss_typename_param_k R       /* The reference type */
        ,   ss_typename_param_k C       /* The enclosing class */
        ,   ss_ptrdiff_t (*PFnOff)()    /* Pointer to function providing offset of property within container */
#ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
        ,   void (C::*PFnSet)(R )   /* Pointer to a member function taking R */
#endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
        >
class method_property_set
    : public internal_property<0, 1, 0>
{
/// \name Member Types
/// @{
private:
    typedef V                                               value_type;
    typedef R                                               reference_type;
    typedef C                                               container_type;
#ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
    typedef method_property_set<V, R, C, PFnOff, PFnSet>    class_type;
#else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
    typedef method_property_set<V, R, C, PFnOff>            class_type;
    typedef member_set_pointer<class_type, R, C>            member_pointer_type;
#endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
/// @}

/// \name Construction
/// @{
#ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
# if defined(STLSOFT_COMPILER_IS_DMC)
public:
# else /* ? compiler */
private:
# endif /* compiler */
    method_property_set()
    {}

private:
    ss_explicit_k method_property_set(reference_type value)
        : m_value(value)
    {}
#else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */

private:
    typedef member_pointer_type PFnSet;

private:
    ss_explicit_k method_property_set(void (C::*pfn)(reference_type ))
    {
        PFnSet f(pfn);
    }
    method_property_set(void (C::*pfn)(reference_type ), reference_type value)
        : m_value(value)
    {
        PFnSet f(pfn);
    }

#endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */

    STLSOFT_DECLARE_TEMPLATE_PARAM_AS_FRIEND(C);
/// @}

/// \name Accessors
/// @{
public:
    /// Provides write-only access to the property
    class_type& operator =(reference_type value)
    {
        ss_ptrdiff_t    offset  =   (*PFnOff)();
        container_type  *pC     =   (container_type*)((ss_byte_t*)this - offset);

#ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
        (pC->*PFnSet)(value);
#else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
        PFnSet::set(pC, &value);
#endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */

        return *this;
    }
/// @}

/// \name Members
/// @{
private:
    value_type  m_value;
/// @}
};


/** \brief This class provides method-based read/write property access
 *
 * \ingroup group__library__properties
 *
 * The containing class defines get and set methods. It also defines a static
 * method that contains the offset of the given property from within the container.
 * Then the template is parameterised with the value type, the set reference type,
 * the get reference type, the container type, the member functions and the offset
 * function.
 */
template<   ss_typename_param_k V       /* The actual property value type */
        ,   ss_typename_param_k RG      /* The get reference type */
        ,   ss_typename_param_k RS      /* The set reference type */
        ,   ss_typename_param_k C       /* The enclosing class */
        ,   ss_ptrdiff_t (*PFnOff)()    /* Pointer to function providing offset of property within container */
#ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
        ,   RG (C::*PFnGet)() const /* Pointer to a const member function returning R */
        ,   void (C::*PFnSet)(RS)   /* Pointer to a member function taking R */
#endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
        >
class method_property_getset
    : public internal_property<1, 1, 0>
{
/// \name Member Types

⌨️ 快捷键说明

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