?
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;
}