#include <boost/typeof/typeof.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost { namespace property {
class not_implemented {};
///Dummy class used as base class for property when detecting whether a property has get/set functions
template<typename Class>
class property_signature {
public:
Class* self() {return 0;}
const Class* self() const {return 0;}
not_implemented get() const;
void set(not_implemented);
};
///Trait to extract return type and argument type of get/set functions
template<typename T>
struct property_get_type;
template<typename ReturnType,typename Class>
struct property_get_type<ReturnType (Class::*)() const>
{
typedef ReturnType type;
};
template<typename ReturnType,typename Class>
struct property_get_type<ReturnType (Class::*)()>
{
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;
};
///Traits class
template<typename Derived,typename Class,typename Signature>
class property_traits
{
private:
typedef BOOST_TYPEOF_TPL(&Signature::get) signature_of_get;
typedef BOOST_TYPEOF_TPL(&Signature::set) signature_of_set;
public:
typedef typename property_get_type<signature_of_get>::type get_return_type;
typedef typename property_set_type<signature_of_set>::type set_argument_type;
typedef boost::mpl::bool_<!boost::is_same<get_return_type,not_implemented>::value> has_get;
typedef boost::mpl::bool_<!boost::is_same<set_argument_type,not_implemented>::value> has_set;
typedef Derived derived_type;
typedef Class class_type;
};
template<typename Traits>
class property_base
{
protected:
typedef typename Traits::derived_type derived_type;
typedef typename Traits::class_type class_type;
derived_type& derived() {return *static_cast<derived_type*>(this);}
const derived_type& derived() const {return *static_cast<const derived_type*>(this);}
public:
class_type* self()
{
size_t offset=derived().offset();
return reinterpret_cast<class_type*>(size_t(this)-offset);
}
const class_type* self() const
{
size_t offset=derived().offset();
return reinterpret_cast<class_type*>(size_t(this)-offset);
}
};
//Enable get-like syntax only when get is implemented.
template<typename Traits,typename HasGet,typename Base=property_base<Traits> >
class property_get : public Base {
public:
typedef typename Traits::get_return_type return_type;
operator return_type() const {return derived().get();}
};
template<typename Traits,typename Base>
class property_get<Traits,boost::mpl::false_,Base> : public Base {};
//Enable set-like syntax only when set is implemented.
template<typename Traits,typename HasSet,typename Base=property_base<Traits> >
class property_set : public Base {
public:
typedef typename Traits::derived_type derived_type;
typedef property_set property_set_type;
typedef typename Traits::set_argument_type argument_type;
derived_type& operator=(argument_type arg) {derived().set(arg);return derived();}
};
template<typename Traits,typename Base>
class property_set<Traits,boost::mpl::false_,Base> : public Base
{
public:
typedef property_set property_set_type;
};
//Enable functionality of property, such as operator=,operator T(), operator[] etc.
template<typename Traits>
class property_selector
: public property_get<Traits,typename Traits::has_get,property_set<Traits,typename Traits::has_set> >
{
};
#define BOOST_PROPERTY(Class,Property,Name)\
struct _Property ## Name ## Impl_ : public \
Property<\
boost::property::property_selector<\
boost::property::property_traits<\
_Property ## Name ## Impl_,\
Class,\
Property<boost::property::property_signature<Class> >\
>\
>\
>{\
public:\
/*Extract the position of this member variable relative to the start of (this) for the Class.*/\
size_t offset() const {return size_t(&((Class*)0)->Name);}\
using property_set_type::operator=;\
} Name;
}}
int main()
{
return 0;
}