📄 method_properties.hpp
字号:
, &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 + -