#include <iostream>
#include <string>
using namespace std;
#include <boost/variant.hpp>
class Value {
int x;
public:
explicit Value(int x) : x(x) {}
Value(Value&&) = default;
Value(const Value&) = delete;
~Value() { x = 100500; }
int peek() const { return x; }
};
Value fa() {
Value a(1);
return a;
}
Value ga() {
Value a(1);
Value& ra = a;
return move(ra);
}
auto ha() {
Value a(1);
return [aa(move(a))]() mutable -> Value { return move(aa); };
}
using Either = boost::variant<Value, string>;
Either&& emove(Either& e) { return static_cast<Either&&>(e); }
Either fe() {
Either a("aaa");
return a;
}
Either ge() {
Either a(Value(123));
Either& ra = a;
// cannot explicitly move, had to trick with static-cast
// return move(ra);
return emove(ra);
}
auto he() {
Either a(Value(456));
cout << "he : " << &a << endl;
// cannot bind to moved
// return [=]() mutable -> Either { return a; };
// return [a(move(a))]() mutable -> Either { return move(a); }
return [&a, aa(emove(a))]() mutable -> Either {
cout << "ll : " << &aa << " != " << &a << endl;
return emove(aa);
};
}
Value peek(Either&& e) {
return boost::get<Value>(emove(e));
}
Value peekpeek(Either e) {
return peek(emove(e));
}
int main() {
cout << boost::get<Value>(ge()).peek() << endl;
cout << boost::get<Value>(he()()).peek() << endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKI2luY2x1ZGUgPGJvb3N0L3ZhcmlhbnQuaHBwPgoKY2xhc3MgVmFsdWUgewoJaW50IHg7CnB1YmxpYzoKCWV4cGxpY2l0IFZhbHVlKGludCB4KSA6IHgoeCkge30KCVZhbHVlKFZhbHVlJiYpID0gZGVmYXVsdDsKCVZhbHVlKGNvbnN0IFZhbHVlJikgPSBkZWxldGU7Cgl+VmFsdWUoKSB7IHggPSAxMDA1MDA7IH0KCQoJaW50IHBlZWsoKSBjb25zdCB7IHJldHVybiB4OyB9Cn07CgpWYWx1ZSBmYSgpIHsKCVZhbHVlIGEoMSk7CglyZXR1cm4gYTsKfQpWYWx1ZSBnYSgpIHsKCVZhbHVlIGEoMSk7CglWYWx1ZSYgcmEgPSBhOwoJcmV0dXJuIG1vdmUocmEpOwp9CmF1dG8gaGEoKSB7CglWYWx1ZSBhKDEpOwoJcmV0dXJuIFthYShtb3ZlKGEpKV0oKSBtdXRhYmxlIC0+IFZhbHVlIHsgcmV0dXJuIG1vdmUoYWEpOyB9Owp9Cgp1c2luZyBFaXRoZXIgPSBib29zdDo6dmFyaWFudDxWYWx1ZSwgc3RyaW5nPjsKCkVpdGhlciYmIGVtb3ZlKEVpdGhlciYgZSkgeyByZXR1cm4gc3RhdGljX2Nhc3Q8RWl0aGVyJiY+KGUpOyB9CgpFaXRoZXIgZmUoKSB7CglFaXRoZXIgYSgiYWFhIik7CglyZXR1cm4gYTsKfQpFaXRoZXIgZ2UoKSB7CglFaXRoZXIgYShWYWx1ZSgxMjMpKTsKCUVpdGhlciYgcmEgPSBhOwoJLy8gY2Fubm90IGV4cGxpY2l0bHkgbW92ZSwgaGFkIHRvIHRyaWNrIHdpdGggc3RhdGljLWNhc3QKCS8vIHJldHVybiBtb3ZlKHJhKTsKCXJldHVybiBlbW92ZShyYSk7Cn0KYXV0byBoZSgpIHsKCUVpdGhlciBhKFZhbHVlKDQ1NikpOwoJY291dCA8PCAiaGUgOiAiIDw8ICZhIDw8IGVuZGw7CgkvLyBjYW5ub3QgYmluZCB0byBtb3ZlZAoJLy8gcmV0dXJuIFs9XSgpIG11dGFibGUgLT4gRWl0aGVyIHsgcmV0dXJuIGE7IH07CgkvLyByZXR1cm4gW2EobW92ZShhKSldKCkgbXV0YWJsZSAtPiBFaXRoZXIgeyByZXR1cm4gbW92ZShhKTsgfQoJcmV0dXJuIFsmYSwgYWEoZW1vdmUoYSkpXSgpIG11dGFibGUgLT4gRWl0aGVyIHsKCQljb3V0IDw8ICJsbCA6ICIgPDwgJmFhIDw8ICIgIT0gIiA8PCAmYSA8PCBlbmRsOwoJCXJldHVybiBlbW92ZShhYSk7Cgl9Owp9CgpWYWx1ZSBwZWVrKEVpdGhlciYmIGUpIHsKCXJldHVybiBib29zdDo6Z2V0PFZhbHVlPihlbW92ZShlKSk7Cn0KVmFsdWUgcGVla3BlZWsoRWl0aGVyIGUpIHsKCXJldHVybiBwZWVrKGVtb3ZlKGUpKTsKfQoKCmludCBtYWluKCkgewoJY291dCA8PCBib29zdDo6Z2V0PFZhbHVlPihnZSgpKS5wZWVrKCkgPDwgZW5kbDsKCWNvdXQgPDwgYm9vc3Q6OmdldDxWYWx1ZT4oaGUoKSgpKS5wZWVrKCkgPDwgZW5kbDsKfQ==