Re: a.k.a. Compile-Tme Reflection вручную №2
От: _nn_  
Дата: 21.04.06 11:35
Оценка:
Здравствуйте, _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);
}
http://rsdn.nemerleweb.com
http://nemerleweb.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.