#pragma once #include #include #pragma warning (disable:4355) 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 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 struct property_get_type; template struct property_get_type { typedef ReturnType type; }; template struct property_get_type { typedef ReturnType type; }; template struct property_set_type; template struct property_set_type { typedef Argument type; }; ///Traits class template 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::type get_return_type; typedef typename property_set_type::type set_argument_type; typedef boost::mpl::bool_::value> has_get; typedef boost::mpl::bool_::value> has_set; typedef Derived derived_type; typedef Class class_type; }; template class property_base { protected: typedef typename Traits::derived_type derived_type; typedef typename Traits::class_type class_type; derived_type& derived() {return *static_cast(this);} const derived_type& derived() const {return *static_cast(this);} public: class_type* self() { size_t offset=derived().offset(); return reinterpret_cast(size_t(this)-offset); } const class_type* self() const { size_t offset=derived().offset(); return reinterpret_cast(size_t(this)-offset); } }; //Enable get-like syntax only when get is implemented. template > class property_get : public Base { public: typedef typename Traits::get_return_type return_type; operator return_type() const {return Base::derived().get();} }; template class property_get : public Base {}; //Enable set-like syntax only when set is implemented. template > 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) {Base::derived().set(arg);return Base::derived();} }; template class property_set : public Base { public: typedef property_set property_set_type; }; //Enable functionality of property, such as operator=,operator T(), operator[] etc. template class property_selector : public property_get > { }; #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 >\ >\ >\ >{\ 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; }}