#include <iostream>
#include <stdexcept>
using namespace std;
class BaseHolder
{
public:
virtual ~BaseHolder(){}
virtual BaseHolder* clone() const = 0;
};
template<typename T>
class HoldData : public BaseHolder
{
public:
HoldData(const T& t_) : t(t_){}
virtual BaseHolder* clone() const {
return new HoldData<T>(t);
}
T getData() {
return t;
}
private:
T t;
};
class Variant
{
public:
Variant() : data(0) {}
template<typename T>
Variant(const T& t) : data(new HoldData<T>(t)){}
Variant(const Variant& other) : data(other.data ? other.data->clone() : 0) {}
~Variant(){delete data;}
template<typename T>
T getData() {
return ((HoldData<T>*)data)->getData();
}
private:
BaseHolder* data;
private:
Variant& operator=(const Variant& other) { return *this;} // Not allowed
};
struct none {};
class Container{
public:
Container() : m1_(0), m2_(0), m3_(0){}
~Container() {
if(m1_)
delete m1_;
if(m2_)
delete m1_;
if(m3_)
delete m1_;
}
none extract() { return none();}
template<typename T>
void insertM1(T obj) {
m1_ = new Variant(obj);
}
template<typename T>
T extractM1() {
if(m1_ != 0)
return m1_->getData<T>();
else
throw std::runtime_error("Element not set");
}
// TODO: implement m2 and m3
Variant *m1_;
Variant *m2_;
Variant *m3_;
};
int main() {
Container obj;
char M1 = 'Z';
obj.insertM1(M1);
char extractedM1 = obj.extractM1<char>();
cout << extractedM1;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RkZXhjZXB0Pgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKCmNsYXNzIEJhc2VIb2xkZXIKewpwdWJsaWM6CiAgdmlydHVhbCB+QmFzZUhvbGRlcigpe30KICB2aXJ0dWFsIEJhc2VIb2xkZXIqIGNsb25lKCkgY29uc3QgPSAwOwp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgVD4KY2xhc3MgSG9sZERhdGEgOiBwdWJsaWMgQmFzZUhvbGRlcgp7CnB1YmxpYzoKICBIb2xkRGF0YShjb25zdCBUJiB0XykgOiB0KHRfKXt9CgogIHZpcnR1YWwgQmFzZUhvbGRlciogY2xvbmUoKSBjb25zdCB7CiAgICByZXR1cm4gbmV3IEhvbGREYXRhPFQ+KHQpOwogIH0KCiAgVCBnZXREYXRhKCkgewoJICByZXR1cm4gdDsKICB9Cgpwcml2YXRlOgogIFQgdDsKfTsKCgpjbGFzcyBWYXJpYW50CnsKcHVibGljOgoKICBWYXJpYW50KCkgOiBkYXRhKDApIHt9CgogIHRlbXBsYXRlPHR5cGVuYW1lIFQ+CiAgVmFyaWFudChjb25zdCBUJiB0KSA6IGRhdGEobmV3IEhvbGREYXRhPFQ+KHQpKXt9CgogIFZhcmlhbnQoY29uc3QgVmFyaWFudCYgb3RoZXIpIDogZGF0YShvdGhlci5kYXRhID8gb3RoZXIuZGF0YS0+Y2xvbmUoKSA6IDApIHt9CiAgflZhcmlhbnQoKXtkZWxldGUgZGF0YTt9CgogIHRlbXBsYXRlPHR5cGVuYW1lIFQ+CiAgVCBnZXREYXRhKCkgewoJICByZXR1cm4gKChIb2xkRGF0YTxUPiopZGF0YSktPmdldERhdGEoKTsKICB9Cgpwcml2YXRlOgogIEJhc2VIb2xkZXIqIGRhdGE7Cgpwcml2YXRlOgogIFZhcmlhbnQmIG9wZXJhdG9yPShjb25zdCBWYXJpYW50JiBvdGhlcikgeyByZXR1cm4gKnRoaXM7fSAvLyBOb3QgYWxsb3dlZAp9OwoKc3RydWN0IG5vbmUge307CgpjbGFzcyBDb250YWluZXJ7CnB1YmxpYzoKCUNvbnRhaW5lcigpIDogbTFfKDApLCBtMl8oMCksIG0zXygwKXt9Cgl+Q29udGFpbmVyKCkgewoJCWlmKG0xXykKCQkJZGVsZXRlIG0xXzsKCQlpZihtMl8pCgkJCWRlbGV0ZSBtMV87CgkJaWYobTNfKQoJCQlkZWxldGUgbTFfOwoJfQoKCW5vbmUgZXh0cmFjdCgpIHsgcmV0dXJuIG5vbmUoKTt9CgoJdGVtcGxhdGU8dHlwZW5hbWUgVD4KCXZvaWQgaW5zZXJ0TTEoVCBvYmopIHsKCQltMV8gPSBuZXcgVmFyaWFudChvYmopOwoJfQoKCXRlbXBsYXRlPHR5cGVuYW1lIFQ+CglUIGV4dHJhY3RNMSgpIHsKCQlpZihtMV8gIT0gMCkKCQkJcmV0dXJuIG0xXy0+Z2V0RGF0YTxUPigpOwoJCWVsc2UKCQkJdGhyb3cgc3RkOjpydW50aW1lX2Vycm9yKCJFbGVtZW50IG5vdCBzZXQiKTsKCX0KCgkvLyBUT0RPOiBpbXBsZW1lbnQgbTIgYW5kIG0zCgoJVmFyaWFudCAqbTFfOwoJVmFyaWFudCAqbTJfOwoJVmFyaWFudCAqbTNfOwp9OwoKaW50IG1haW4oKSB7CgoJQ29udGFpbmVyIG9iajsKCQoJY2hhciBNMSA9ICdaJzsKCW9iai5pbnNlcnRNMShNMSk7CgoJY2hhciBleHRyYWN0ZWRNMSA9IG9iai5leHRyYWN0TTE8Y2hhcj4oKTsKCWNvdXQgPDwgZXh0cmFjdGVkTTE7CgoJcmV0dXJuIDA7Cn0=