[ create a new paste ] login | about

Link: http://codepad.org/MD5knINj    [ raw code | output | fork ]

C++, pasted on Oct 19:
#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;
}


Output:
1
2
3
t.cpp: In member function 'boost::property::property_get<Traits, HasGet, Base>::operator typename Traits::get_return_type() const':
Line 87: error: there are no arguments to 'derived' that depend on a template parameter, so a declaration of 'derived' must be available
compilation terminated due to -Wfatal-errors.


Create a new paste based on this one


Comments: