codepad
[
create a new paste
]
login
|
about
Language:
C
C++
D
Haskell
Lua
OCaml
PHP
Perl
Plain Text
Python
Ruby
Scheme
Tcl
#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; }
Private
[
?
]
Run code
Submit