#include <iostream>
template<class T>
struct generic_property {
virtual T getValue() const = 0;
virtual void setValue(T const&) = 0;
protected:
virtual ~generic_property() {}
};
template<class D, class T, void(D::*set)(T const&), T(D::*get)() const>
struct property:generic_property<T> {
T getValue() const final {
return (self->*get)();
}
void setValue(T const& t) final {
(self->*set)(t);
}
property( D* s ):self(s) {}
// cannot usually safely copy/move/trivial:
property() = delete;
property( property const& ) = delete;
property& operator=( property const& ) = delete;
private:
D* self = 0;
};
struct Bob {
void setFoo( int const& i ) { std::cout << i << " set\n"; }
int getFoo() const { std::cout << 42 << " get\n"; return 42; }
property<Bob, int, &Bob::setFoo, &Bob::getFoo> foo;
Bob():foo(this) {}
};
int main() {
Bob bob;
std::cout << bob.foo.getValue() << "\n";
bob.foo.setValue(3);
generic_property<int>& foo = bob.foo;
foo.setValue(4);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKIAogICAgdGVtcGxhdGU8Y2xhc3MgVD4KICAgIHN0cnVjdCBnZW5lcmljX3Byb3BlcnR5IHsKICAgICAgdmlydHVhbCBUIGdldFZhbHVlKCkgY29uc3QgPSAwOwogICAgICB2aXJ0dWFsIHZvaWQgc2V0VmFsdWUoVCBjb25zdCYpID0gMDsKICAgIHByb3RlY3RlZDoKICAgICAgdmlydHVhbCB+Z2VuZXJpY19wcm9wZXJ0eSgpIHt9CiAgICB9OwogICAgdGVtcGxhdGU8Y2xhc3MgRCwgY2xhc3MgVCwgdm9pZChEOjoqc2V0KShUIGNvbnN0JiksIFQoRDo6KmdldCkoKSBjb25zdD4KICAgIHN0cnVjdCBwcm9wZXJ0eTpnZW5lcmljX3Byb3BlcnR5PFQ+IHsKICAgIAlUIGdldFZhbHVlKCkgY29uc3QgZmluYWwgewogICAgCQlyZXR1cm4gKHNlbGYtPipnZXQpKCk7CiAgICAJfQogICAgCXZvaWQgc2V0VmFsdWUoVCBjb25zdCYgdCkgZmluYWwgewogICAgCQkoc2VsZi0+KnNldCkodCk7CiAgICAJfQogICAgCXByb3BlcnR5KCBEKiBzICk6c2VsZihzKSB7fQoKCS8vIGNhbm5vdCB1c3VhbGx5IHNhZmVseSBjb3B5L21vdmUvdHJpdmlhbDogICAgCQogICAgCXByb3BlcnR5KCkgPSBkZWxldGU7CiAgICAJcHJvcGVydHkoIHByb3BlcnR5IGNvbnN0JiApID0gZGVsZXRlOwogICAgCXByb3BlcnR5JiBvcGVyYXRvcj0oIHByb3BlcnR5IGNvbnN0JiApID0gZGVsZXRlOwogICAgcHJpdmF0ZToKCSAgICBEKiBzZWxmID0gMDsKICAgIH07CiAgICAKICAgIHN0cnVjdCBCb2IgewogICAgCXZvaWQgc2V0Rm9vKCBpbnQgY29uc3QmIGkgKSB7IHN0ZDo6Y291dCA8PCBpIDw8ICIgc2V0XG4iOyB9CiAgICAJaW50IGdldEZvbygpIGNvbnN0IHsgc3RkOjpjb3V0IDw8IDQyIDw8ICIgZ2V0XG4iOyByZXR1cm4gNDI7IH0KICAgIAlwcm9wZXJ0eTxCb2IsIGludCwgJkJvYjo6c2V0Rm9vLCAmQm9iOjpnZXRGb28+IGZvbzsKICAgIAkKICAgIAlCb2IoKTpmb28odGhpcykge30KICAgIH07CgppbnQgbWFpbigpIHsKCUJvYiBib2I7CglzdGQ6OmNvdXQgPDwgYm9iLmZvby5nZXRWYWx1ZSgpIDw8ICJcbiI7Cglib2IuZm9vLnNldFZhbHVlKDMpOwoJZ2VuZXJpY19wcm9wZXJ0eTxpbnQ+JiBmb28gPSBib2IuZm9vOwoJZm9vLnNldFZhbHVlKDQpOwp9