Methodenzeiger als Template-Argument - Defaultwerte



  • Hallo da!
    Schön, dass ihr wieder da seid.

    Vielleicht erinnert ihr euch noch an diesen Thread, ich konnte jetzt den Umstand ausnutzen, dass VC++ beim letzten Argument doch den nullptr als default akzeptiert. Zusammen mit decltype sieht das jetzt mMn sehr schön aus, mal davon ab, dass Intellisense darauf abraucht:

    #include <iostream>
    
    template< typename ValueType, typename ClassType, ValueType(ClassType::*Getter)() const = nullptr >
    struct getter {
    	static ValueType get(const ClassType* this_)
    	{
    		return (this_->*Getter)();
    	}
    
    	static bool is_null() {
    		return Getter == nullptr;
    	}
    };
    
    template< typename ValueType, typename ClassType, void(ClassType::*Setter)(ValueType) = nullptr >
    struct setter {
    	template< typename ValInType >
    	static void set(ClassType* this_, ValInType&& val)
    	{
    		(this_->*Setter)(std::forward<ValInType>(val));
    	}
    
    	static bool is_null() {
    		return Setter == nullptr;
    	}
    };
    
    template< typename ValueType, typename ClassType, bool(ClassType::*Validator)(ValueType) const = nullptr >
    struct validator {
    	static bool validate(const ClassType* this_, const ValueType& val) {
    		if (!is_null()) {
    			return (this_->*Validator)(val);
    		}
    		else {
    			return true;
    		}
    	}
    
    	static bool is_null() {
    		return Validator == nullptr;
    	}
    };
    
    template< typename ValueType, typename ClassType, void(ClassType::*Options)() = nullptr >
    struct options {
    	static void option()
    	{}
    };
    
    template < typename ValueType, typename ClassType,
    	typename Getter,
    	typename Setter = setter<ValueType,ClassType>,
    	typename Validator = validator<ValueType,ClassType>,
    	typename Options = options<ValueType,ClassType>
    >
    struct StaticProperty
    {
    
    	ValueType get(const ClassType* this_) {
    		return Getter::get(this_);
    	}
    
    	template < typename ValTypeIn >
    	void set(ClassType* this_, ValTypeIn&& val)
    	{
    		Setter::set(this_, std::forward<ValTypeIn>(val));
    	}
    
    	template < typename ValTypeIn >
    	void validate(ClassType* this_, ValTypeIn&& val)
    	{
    		Validator::validate(this_, std::forward<ValTypeIn>(val));
    	}
    private:
    
    };
    
    template< typename... Types >
    struct type_list
    {};
    
    template< typename Ret, typename Class, typename... Args >
    struct method_types {
    	using ret_type = Ret;
    	using class_type = Class;
    	using arg_types = type_list<Args...>;
    };
    
    template< typename ClassType, typename Ret, typename... Args >
    method_types<Ret, ClassType, Args...> deduce(Ret(ClassType::*arg)(Args...) const);
    
    #define StaticPropertyR(Getter) \
    	StaticProperty< typename decltype(deduce(Getter))::ret_type, typename decltype(deduce(Getter))::class_type, \
    		getter< typename decltype(deduce(Getter))::ret_type, typename decltype(deduce(Getter))::class_type, Getter > \
    	>
    
    #define StaticPropertyRS(Getter,Setter) \
    	StaticProperty< typename decltype(deduce(Getter))::ret_type, typename decltype(deduce(Getter))::class_type, \
    		getter< typename decltype(deduce(Getter))::ret_type, typename decltype(deduce(Getter))::class_type, Getter >, \
    		setter< typename decltype(deduce(Getter))::ret_type, typename decltype(deduce(Getter))::class_type, Setter > \
    	>
    
    #define StaticPropertyRSV(Getter,Setter,Validator) \
    	StaticProperty< typename decltype(deduce(Getter))::ret_type, typename decltype(deduce(Getter))::class_type, \
    		getter< typename decltype(deduce(Getter))::ret_type, typename decltype(deduce(Getter))::class_type, Getter >, \
    		setter< typename decltype(deduce(Getter))::ret_type, typename decltype(deduce(Getter))::class_type, Setter >, \
    		validator< typename decltype(deduce(Getter))::ret_type, typename decltype(deduce(Getter))::class_type, Validator > \
    	>
    
    struct test_class {
    	test_class() {
    	}
    
    	int get_property() const {
    		return value_;
    	}
    
    	void set_property(int value) {
    		value_ = value;
    	}
    
    	bool validate(int value) const {
    		return true;
    	}
    
    private:
    	int value_;
    };
    
    StaticPropertyR(&test_class::get_property) my_prop;
    StaticPropertyRS(&test_class::get_property, &test_class::set_property) my_prop2;
    StaticPropertyRSV(&test_class::get_property, &test_class::set_property, &test_class::validate) my_prop3;
    
    int main()
    {
    	test_class test;
    
    	my_prop3.set(&test, 4);
    	std::cout << my_prop3.get(&test);
    
    	return 0;
    }
    

Anmelden zum Antworten