#include <iostream>
using namespace std;
class Foo {
enum OpState {
None ,
PlusState ,
NotState ,
};
public:
friend Foo& operator+(Foo& lhs, const Foo& rhs) {
cout << "operator+(Foo& lhs, const Foo& rhs)" << endl;
if(lhs.opState == NotState) {
return lhs.operatorexclamativeplus(rhs);
}
return lhs;
}
Foo& operator+() {
cout << "operator+()" << endl;
opState = PlusState;
return *this;
}
Foo& operator!() {
cout << "operator!()" << endl;
switch(opState) {
case PlusState:
operatorexclamativeplus();
opState = None;
break;
default:
opState = NotState;
break;
}
return *this;
}
private:
void operatorexclamativeplus() {
cout << "operatorexclamativeplus()" << endl;
}
Foo& operatorexclamativeplus(const Foo& rhs) {
cout << "operatorexclamativeplus(const Foo& rhs)" << endl;
return *this;
}
OpState opState;
};
int main() {
Foo x;
Foo y;
!+x;
Foo z = y !+ x;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKY2xhc3MgRm9vIHsKICAgIGVudW0gT3BTdGF0ZSB7CiAgICAJTm9uZSAsCiAgICAJUGx1c1N0YXRlICwKICAgIAlOb3RTdGF0ZSAsCiAgICB9OwoKcHVibGljOgogICAgZnJpZW5kIEZvbyYgb3BlcmF0b3IrKEZvbyYgbGhzLCBjb25zdCBGb28mIHJocykgewoJCWNvdXQgPDwgIm9wZXJhdG9yKyhGb28mIGxocywgY29uc3QgRm9vJiByaHMpIiA8PCBlbmRsOwoJCWlmKGxocy5vcFN0YXRlID09IE5vdFN0YXRlKSB7CgkJICAgIHJldHVybiBsaHMub3BlcmF0b3JleGNsYW1hdGl2ZXBsdXMocmhzKTsKCQl9CgkJcmV0dXJuIGxoczsKCX0KCiAgIEZvbyYgb3BlcmF0b3IrKCkgewogICAJICAgY291dCA8PCAib3BlcmF0b3IrKCkiIDw8IGVuZGw7CiAgICAgICBvcFN0YXRlID0gUGx1c1N0YXRlOwogICAgICAgcmV0dXJuICp0aGlzOwogICB9CiAgIEZvbyYgb3BlcmF0b3IhKCkgewogICAJICAgY291dCA8PCAib3BlcmF0b3IhKCkiIDw8IGVuZGw7CiAgICAgICBzd2l0Y2gob3BTdGF0ZSkgewogICAgICAgY2FzZSBQbHVzU3RhdGU6CiAgICAgICAgICAgb3BlcmF0b3JleGNsYW1hdGl2ZXBsdXMoKTsKICAgICAgICAgICBvcFN0YXRlID0gTm9uZTsKICAgICAgICAgICBicmVhazsgICAgICAgCiAgICAgICBkZWZhdWx0OgogICAgICAgICAgIG9wU3RhdGUgPSBOb3RTdGF0ZTsKICAgICAgICAgICBicmVhazsgICAgICAgCiAgICAgICB9CiAgICAgICByZXR1cm4gKnRoaXM7CiAgIH0KCnByaXZhdGU6CiAgICB2b2lkIG9wZXJhdG9yZXhjbGFtYXRpdmVwbHVzKCkgewogICAJICAgY291dCA8PCAib3BlcmF0b3JleGNsYW1hdGl2ZXBsdXMoKSIgPDwgZW5kbDsKICAgIH0KICAgIEZvbyYgb3BlcmF0b3JleGNsYW1hdGl2ZXBsdXMoY29uc3QgRm9vJiByaHMpIHsKICAgCSAgIGNvdXQgPDwgIm9wZXJhdG9yZXhjbGFtYXRpdmVwbHVzKGNvbnN0IEZvbyYgcmhzKSIgPDwgZW5kbDsKICAgCSAgIHJldHVybiAqdGhpczsKICAgIH0KCiAgICBPcFN0YXRlIG9wU3RhdGU7Cn07CgoKaW50IG1haW4oKSB7CglGb28geDsKCUZvbyB5OwoJISt4OwoJRm9vIHogPSB5ICErIHg7CglyZXR1cm4gMDsKfQ==