Здравствуйте, _nn_, Вы писали:
Версия 2

Добавленны макросы для улучшения читаемости:
class a
{
...
// Methods
DECL_METHODS0(void (this_type::*)())
// Variables
DECL_VARIABLES0(int this_type::*)
// Static Methods
DECL_STATIC_METHODS0(void (*)())
// Static Variables
DECL_STATIC_VARIABLES0(int*)
}
DEF_METHODS0(a, f)
DEF_VARIABLES0(a, i)
DEF_STATIC_METHODS0(a, sf)
DEF_STATIC_VARIABLES0(a, si)
Можно сделать с переменным количеством аргументов если каждый аргумент обернуть в скобки.
Теперь вызов функций/переменных стал проще:
// Invoke method !
(t.*get_method<T, 0>::value)();
// Invoke variable !
t.*get_variable<T, 0>::value = 2;
// Invoke static method !
(*get_static_method<T, 0>::value)();
// Invoke static method !
*get_static_variable<T, 0>::value = 2;
Код:
#include <boost/mpl/size.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/at.hpp>
#include <boost/preprocessor/cat.hpp>
#define DEF_CLASS0(classname) \
class a \
{ \
public: \
typedef classname this_type; \
typedef boost::mpl::vector<> base_type;
#define CTR_TYPE(name) \
BOOST_PP_CAT(name, _type)
#define CTR_TYPES(name) \
BOOST_PP_CAT(name, s_type)
#define CTR_COUNT(name) \
BOOST_PP_CAT(name, s_count)
#define CTR_VAR(name) \
BOOST_PP_CAT(name, s)
#define DECL_GEN(name, type) \
typedef boost::mpl::vector<type> CTR_TYPES(name); \
static const size_t CTR_COUNT(name) = boost::mpl::size<CTR_TYPES(name)>::value; \
static const CTR_TYPE(name) CTR_VAR(name)[CTR_COUNT(name)];
#define DECL_METHODS0(type) \
typedef void (this_type::*method_type)(); \
DECL_GEN(method, type)
#define DECL_VARIABLES0(type) \
typedef void* this_type::*variable_type; \
DECL_GEN(variable, type)
#define DECL_STATIC_METHODS0(type) \
typedef void (*static_method_type)(); \
DECL_GEN(static_method, type)
#define DECL_STATIC_VARIABLES0(type) \
typedef void* static_variable_type; \
DECL_GEN(static_variable, type)
#define DEF_GEN0(name, classname, t) \
const classname::CTR_TYPE(name) classname::CTR_VAR(name)[classname::CTR_COUNT(name)] = \
{ \
reinterpret_cast<classname::CTR_TYPE(name)>(&classname::t) \
};
#define DEF_METHODS0(classname, f) \
DEF_GEN0(method, classname, f)
#define DEF_VARIABLES0(classname, f) \
DEF_GEN0(variable, classname, f)
#define DEF_STATIC_METHODS0(classname, f) \
DEF_GEN0(static_method, classname, f)
#define DEF_STATIC_VARIABLES0(classname, f) \
DEF_GEN0(static_variable, classname, f)
DEF_CLASS0(a)
public:
// Methods
void f()
{
i = 1;
}
// Variables
int i;
// Static Methods
static void sf()
{
si = 1;
}
// Static Variables
static int si;
// Methods
DECL_METHODS0(void (this_type::*)())
// Variables
DECL_VARIABLES0(int this_type::*)
// Static Methods
DECL_STATIC_METHODS0(void (*)())
// Static Variables
DECL_STATIC_VARIABLES0(int*)
};
int a::si;
DEF_METHODS0(a, f)
DEF_VARIABLES0(a, i)
DEF_STATIC_METHODS0(a, sf)
DEF_STATIC_VARIABLES0(a, si)
// get_name_type
// get_name_type<T, N>::type
#define GET_TYPE_GEN(name) \
template<typename T, size_t N> \
struct BOOST_PP_CAT(get_, CTR_TYPE(name)) \
{ \
typedef typename boost::mpl::at< \
typename T::CTR_TYPES(name), \
boost::mpl::int_<N> \
>::type type; \
};
GET_TYPE_GEN(method)
GET_TYPE_GEN(variable)
GET_TYPE_GEN(static_method)
GET_TYPE_GEN(static_variable)
// get_name
// get_name<T, N>::value
#define GET_GEN(name) \
template<typename T, size_t N> \
struct BOOST_PP_CAT(get_, name) \
{ \
typedef typename BOOST_PP_CAT(get_, BOOST_PP_CAT(name, _type))<T, N>::type type; \
static const type value; \
}; \
template<typename T, size_t N> \
const typename BOOST_PP_CAT(get_, name)<T, N>::type BOOST_PP_CAT(get_, name)<T, N>::value = \
reinterpret_cast<typename BOOST_PP_CAT(get_, name)<T, N>::type>(T::CTR_VAR(name)[N]);
GET_GEN(method)
GET_GEN(variable)
GET_GEN(static_method)
GET_GEN(static_variable)
template<typename T>
void method(T& t)
{
// Invoke method !
(t.*get_method<T, 0>::value)();
}
template<typename T>
void variable(T& t)
{
// Invoke variable !
t.*get_variable<T, 0>::value = 2;
}
template<typename T>
void static_method(T& t)
{
// Invoke static method !
(*get_static_method<T, 0>::value)();
}
template<typename T>
void static_variable(T& t)
{
// Invoke static method !
*get_static_variable<T, 0>::value = 2;
}
int main()
{
a x;
method(x);
variable(x);
static_method(x);
static_variable(x);
}