#include <cstdio>
#include <functional>
template <class T>
class Property {
T v;
public:
Property(const Property&p) {*this=static_cast<T>(p);}
//Property() { printf("ctor %X\n", this);}
Property(){}
Property& operator=(const Property& src) { return*this=static_cast<T>(src); }
Property& operator=(const T& src) {
printf("write %X\n", this);
v = src;
return *this;
}
operator T() const {
printf("Read %X\n", this);
return v;
}
};
template <class T>
class Property2 {
typedef T(*Gfn)();
typedef void(*Sfn)(T);
Gfn gfn;
Sfn sfn;
public:
Property2(const Property2&p) {*this=static_cast<T>(p);}
//Property2() { printf("ctor %X\n", this);}
Property2(Gfn gfn_, Sfn sfn_):gfn(gfn_), sfn(sfn_) {}
Property2& operator=(const Property2& src) { return*this=static_cast<T>(src); }
Property2& operator=(const T& src) {
printf("write %X\n", this);
sfn(src);
return *this;
}
operator T() const {
printf("Read %X\n", this);
return gfn();
}
};
void set(int v) {}
int get() {return 9;}
Property<int> a, b;
Property2<int> c(get,set), d(get,set);
int main(){
a=b=5;
c=d=11;
a=c=b=d=15;
}
I2luY2x1ZGUgPGNzdGRpbz4KI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CnRlbXBsYXRlIDxjbGFzcyBUPgpjbGFzcyBQcm9wZXJ0eSB7CglUIHY7CnB1YmxpYzoKCVByb3BlcnR5KGNvbnN0IFByb3BlcnR5JnApIHsqdGhpcz1zdGF0aWNfY2FzdDxUPihwKTt9CgkvL1Byb3BlcnR5KCkgeyBwcmludGYoImN0b3IgJVhcbiIsIHRoaXMpO30KCVByb3BlcnR5KCl7fQoJUHJvcGVydHkmIG9wZXJhdG9yPShjb25zdCBQcm9wZXJ0eSYgc3JjKSB7IHJldHVybip0aGlzPXN0YXRpY19jYXN0PFQ+KHNyYyk7IH0KCVByb3BlcnR5JiBvcGVyYXRvcj0oY29uc3QgVCYgc3JjKSB7CgkJcHJpbnRmKCJ3cml0ZSAlWFxuIiwgdGhpcyk7CgkJdiA9IHNyYzsgCgkJcmV0dXJuICp0aGlzOyAKCX0KCW9wZXJhdG9yIFQoKSBjb25zdCB7CgkJcHJpbnRmKCJSZWFkICVYXG4iLCB0aGlzKTsKCQlyZXR1cm4gdjsKCX0KfTsKCnRlbXBsYXRlIDxjbGFzcyBUPgpjbGFzcyBQcm9wZXJ0eTIgewoJdHlwZWRlZiBUKCpHZm4pKCk7Cgl0eXBlZGVmIHZvaWQoKlNmbikoVCk7CglHZm4gZ2ZuOwoJU2ZuIHNmbjsKcHVibGljOgoJUHJvcGVydHkyKGNvbnN0IFByb3BlcnR5MiZwKSB7KnRoaXM9c3RhdGljX2Nhc3Q8VD4ocCk7fQoJLy9Qcm9wZXJ0eTIoKSB7IHByaW50ZigiY3RvciAlWFxuIiwgdGhpcyk7fQoJUHJvcGVydHkyKEdmbiBnZm5fLCBTZm4gc2ZuXyk6Z2ZuKGdmbl8pLCBzZm4oc2ZuXykge30KCVByb3BlcnR5MiYgb3BlcmF0b3I9KGNvbnN0IFByb3BlcnR5MiYgc3JjKSB7IHJldHVybip0aGlzPXN0YXRpY19jYXN0PFQ+KHNyYyk7IH0KCVByb3BlcnR5MiYgb3BlcmF0b3I9KGNvbnN0IFQmIHNyYykgewoJCXByaW50Zigid3JpdGUgJVhcbiIsIHRoaXMpOwoJCXNmbihzcmMpOwoJCXJldHVybiAqdGhpczsgCgl9CglvcGVyYXRvciBUKCkgY29uc3QgewoJCXByaW50ZigiUmVhZCAlWFxuIiwgdGhpcyk7CgkJcmV0dXJuIGdmbigpOwoJfQp9OwoKdm9pZCBzZXQoaW50IHYpIHt9CmludCBnZXQoKSB7cmV0dXJuIDk7fQoKUHJvcGVydHk8aW50PiBhLCBiOwpQcm9wZXJ0eTI8aW50PiBjKGdldCxzZXQpLCBkKGdldCxzZXQpOwppbnQgbWFpbigpewoJYT1iPTU7CgljPWQ9MTE7CglhPWM9Yj1kPTE1Owp9Cg==