#include <boost/typeof/typeof.hpp>
#include <iostream>
template<typename T>
struct property_get_type;
template<typename ReturnType,typename Class>
struct property_get_type<ReturnType (Class::*)() const>
{
typedef ReturnType type;
};
template<typename T>
struct property_set_type;
template<typename ReturnType,typename Class,typename Argument>
struct property_set_type<ReturnType (Class::*)(Argument)>
{
typedef Argument type;
};
template <class Signeture>
class signeture
{
typedef BOOST_TYPEOF_TPL(&Signeture::get) get_signeture_type;
typedef BOOST_TYPEOF_TPL(&Signeture::set) set_signeture_type;
public:
typedef typename property_get_type<get_signeture_type>::type get_return_type;
typedef typename property_set_type<set_signeture_type>::type set_argument_type;
};
template <class Class>
struct get_drived
{
virtual const Class* self() const { return 0; }
};
#define MY_PROPERTY(Property, Class, Name) \
struct Property##_##Class : public signeture<Property<get_drived<Class> > >, public Property<get_drived<Class> >\
{\
typedef Property<get_drived<Class> > base_type;\
get_return_type get() const { return static_cast<const base_type*>(this)->get(); }\
void set(set_argument_type v) { static_cast<base_type*>(this)->set(v); }\
const Class* self() const { return reinterpret_cast<Class*>(size_t(this)-offset()); }\
size_t offset() const {\
union {\
Class* class_pointer;\
size_t rep;\
} c;\
c.rep=0;\
return size_t(&c.class_pointer->Name);\
}\
Property##_##Class & operator=(set_argument_type v) { set(v); return *this; }\
operator get_return_type () const { return get(); }\
} Name
class my_class
{
template <class Base>
struct my_property : Base
{
double get() const { return arg_; }
void set(double v) {
arg_ = v;
this->self()->setter_info(); }
private:
double arg_;
};
void setter_info() const {
std::cout << "call setter" << value << std::endl; }
public:
MY_PROPERTY(my_property, my_class, value);
};
int main()
{
my_class m;
m.value = 5;
double xx = m.value;
return 0;
}