#include <iostream>
#include <functional>
#include <math.h>
using namespace std;
template<class VarType>class Proxy{
VarType& Var;
typedef const VarType& CVarRef;
std::function<void(CVarRef)> Setter;
std::function<CVarRef()> Getter;
public:
Proxy(VarType& Var,std::function<void(CVarRef Val)> Setter=nullptr,std::function<CVarRef()> Getter=nullptr):Var(Var),Setter(Setter),Getter(Getter){}
~Proxy(){}
inline operator CVarRef()const{return Getter?Getter():Var;}
inline const Proxy& operator=(CVarRef NewValue)const{
if(Setter)Setter(NewValue);
else Var=NewValue;
return *this;
}
};
class Hero{
int _Exp;
int _Level;
public:
// Variables.
Proxy<int> Exp;
Proxy<const int> Level;
// Constructor.
Hero(int StartingExp=0):_Exp(StartingExp),_Level(sqrt(StartingExp)),Exp(_Exp,bind(&Hero::SetExp,this,placeholders::_1)),Level(_Level){}
// Destructor.
~Hero(){}
// Functions.
void SetExp(const int& NewExp){
_Exp=NewExp;
_Level=sqrt(NewExp);
}
// Function Pointers.
// Operators.
};
ostream& operator<<(ostream& stream,const Hero& rhs){
return stream<<"Hero of level "<<rhs.Level<<" with "<<rhs.Exp<<" exp.";
}
int main(){
Hero Bob;
Bob.Exp=44;
//Bob.Level=99;
cout<<Bob<<endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KI2luY2x1ZGUgPG1hdGguaD4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKdGVtcGxhdGU8Y2xhc3MgVmFyVHlwZT5jbGFzcyBQcm94eXsKICAgIFZhclR5cGUmIFZhcjsKICAgIHR5cGVkZWYgY29uc3QgVmFyVHlwZSYgQ1ZhclJlZjsKICAgIHN0ZDo6ZnVuY3Rpb248dm9pZChDVmFyUmVmKT4gU2V0dGVyOwogICAgc3RkOjpmdW5jdGlvbjxDVmFyUmVmKCk+IEdldHRlcjsKcHVibGljOgogICAgUHJveHkoVmFyVHlwZSYgVmFyLHN0ZDo6ZnVuY3Rpb248dm9pZChDVmFyUmVmIFZhbCk+IFNldHRlcj1udWxscHRyLHN0ZDo6ZnVuY3Rpb248Q1ZhclJlZigpPiBHZXR0ZXI9bnVsbHB0cik6VmFyKFZhciksU2V0dGVyKFNldHRlciksR2V0dGVyKEdldHRlcil7fQogICAgflByb3h5KCl7fQogICAgaW5saW5lIG9wZXJhdG9yIENWYXJSZWYoKWNvbnN0e3JldHVybiBHZXR0ZXI/R2V0dGVyKCk6VmFyO30KICAgIGlubGluZSBjb25zdCBQcm94eSYgb3BlcmF0b3I9KENWYXJSZWYgTmV3VmFsdWUpY29uc3R7CiAgICAgICAgaWYoU2V0dGVyKVNldHRlcihOZXdWYWx1ZSk7CiAgICAgICAgZWxzZSBWYXI9TmV3VmFsdWU7CiAgICAgICAgcmV0dXJuICp0aGlzOwogICAgfQp9OwpjbGFzcyBIZXJvewogICAgaW50IF9FeHA7CiAgICBpbnQgX0xldmVsOwpwdWJsaWM6CiAgICAvLyBWYXJpYWJsZXMuCiAgICBQcm94eTxpbnQ+IEV4cDsKICAgIFByb3h5PGNvbnN0IGludD4gTGV2ZWw7CiAgICAvLyBDb25zdHJ1Y3Rvci4KICAgIEhlcm8oaW50IFN0YXJ0aW5nRXhwPTApOl9FeHAoU3RhcnRpbmdFeHApLF9MZXZlbChzcXJ0KFN0YXJ0aW5nRXhwKSksRXhwKF9FeHAsYmluZCgmSGVybzo6U2V0RXhwLHRoaXMscGxhY2Vob2xkZXJzOjpfMSkpLExldmVsKF9MZXZlbCl7fQogICAgLy8gRGVzdHJ1Y3Rvci4KICAgIH5IZXJvKCl7fQogICAgLy8gRnVuY3Rpb25zLgogICAgdm9pZCBTZXRFeHAoY29uc3QgaW50JiBOZXdFeHApewogICAgICAgIF9FeHA9TmV3RXhwOwogICAgICAgIF9MZXZlbD1zcXJ0KE5ld0V4cCk7CiAgICB9CiAgICAvLyBGdW5jdGlvbiBQb2ludGVycy4KICAgIC8vIE9wZXJhdG9ycy4KfTsKb3N0cmVhbSYgb3BlcmF0b3I8PChvc3RyZWFtJiBzdHJlYW0sY29uc3QgSGVybyYgcmhzKXsKICAgIHJldHVybiBzdHJlYW08PCJIZXJvIG9mIGxldmVsICI8PHJocy5MZXZlbDw8IiB3aXRoICI8PHJocy5FeHA8PCIgZXhwLiI7Cn0KCmludCBtYWluKCl7CglIZXJvIEJvYjsKCUJvYi5FeHA9NDQ7CgkvL0JvYi5MZXZlbD05OTsKCWNvdXQ8PEJvYjw8ZW5kbDsKfQ==