#include <iostream>
#include <memory>
#include <vector>
using namespace std;
enum class CUSTOM_TYPE : std::uint32_t
{
CHAR_TYPE,
INT_TYPE,
FLOAT_TYPE,
DOUBLE_TYPE,
CLASS_TYPE
};
struct Holder
{
CUSTOM_TYPE type;
std::unique_ptr<void, std::function<void(void*)>> data;
template<typename T>
Holder(CUSTOM_TYPE type, T* data_ptr)
{
auto deleter = [](void* data) {
delete static_cast<T*>(data);
};
this->type = type;
this->data = std::unique_ptr<void, std::function<void(void*)>>(data_ptr, deleter);
}
template<typename T>
T* get()
{
return static_cast<T *>(this->data.get());
}
};
class Test
{
private:
std::string word;
public:
Test(std::string word) : word(word) { std::cout<<"CONSTRUCTED\n"; }
~Test() { std::cout<<"DESTRUCTED\n"; }
void print()
{
std::cout<<this->word<<"\n";
}
};
int main() {
std::vector<Holder> container;
container.push_back(Holder{CUSTOM_TYPE::CHAR_TYPE, new char('A')});
container.emplace_back(Holder{CUSTOM_TYPE::CHAR_TYPE, new char('B')});
container.emplace_back(Holder{CUSTOM_TYPE::INT_TYPE, new int(1024)});
container.emplace_back(Holder{CUSTOM_TYPE::FLOAT_TYPE, new float(98.98397)});
container.emplace_back(Holder{CUSTOM_TYPE::DOUBLE_TYPE, new double(99.9942999997)});
container.emplace_back(Holder{CUSTOM_TYPE::CLASS_TYPE, new Test("HELLO")});
container.emplace_back(Holder{CUSTOM_TYPE::CLASS_TYPE, new Test("WORLD")});
for (Holder &h : container)
{
switch(h.type)
{
case CUSTOM_TYPE::CHAR_TYPE: {
std::cout<<*h.get<char>()<<"\n";
}
break;
case CUSTOM_TYPE::INT_TYPE: {
std::cout<<*h.get<int>()<<"\n";
}
break;
case CUSTOM_TYPE::FLOAT_TYPE: {
std::cout<<*h.get<float>()<<"\n";
}
break;
case CUSTOM_TYPE::DOUBLE_TYPE: {
std::cout<<*h.get<double>()<<"\n";
}
break;
case CUSTOM_TYPE::CLASS_TYPE: {
h.get<Test>()->print();
}
break;
}
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWVtb3J5PgojaW5jbHVkZSA8dmVjdG9yPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCgplbnVtIGNsYXNzIENVU1RPTV9UWVBFIDogc3RkOjp1aW50MzJfdAp7CglDSEFSX1RZUEUsCglJTlRfVFlQRSwKCUZMT0FUX1RZUEUsCglET1VCTEVfVFlQRSwKCUNMQVNTX1RZUEUKfTsKCnN0cnVjdCBIb2xkZXIKewoJQ1VTVE9NX1RZUEUgdHlwZTsKCXN0ZDo6dW5pcXVlX3B0cjx2b2lkLCBzdGQ6OmZ1bmN0aW9uPHZvaWQodm9pZCopPj4gZGF0YTsKCQoJdGVtcGxhdGU8dHlwZW5hbWUgVD4KCUhvbGRlcihDVVNUT01fVFlQRSB0eXBlLCBUKiBkYXRhX3B0cikKCXsKCQlhdXRvIGRlbGV0ZXIgPSBbXSh2b2lkKiBkYXRhKSB7CgkJCWRlbGV0ZSBzdGF0aWNfY2FzdDxUKj4oZGF0YSk7CgkJfTsKCQkKCQl0aGlzLT50eXBlID0gdHlwZTsKCQl0aGlzLT5kYXRhID0gc3RkOjp1bmlxdWVfcHRyPHZvaWQsIHN0ZDo6ZnVuY3Rpb248dm9pZCh2b2lkKik+PihkYXRhX3B0ciwgZGVsZXRlcik7Cgl9CgkKCXRlbXBsYXRlPHR5cGVuYW1lIFQ+CglUKiBnZXQoKQoJewoJCXJldHVybiBzdGF0aWNfY2FzdDxUICo+KHRoaXMtPmRhdGEuZ2V0KCkpOwoJfQp9OwoKY2xhc3MgVGVzdAp7Cglwcml2YXRlOgoJCXN0ZDo6c3RyaW5nIHdvcmQ7CgkJCglwdWJsaWM6CgkJVGVzdChzdGQ6OnN0cmluZyB3b3JkKSA6IHdvcmQod29yZCkgeyBzdGQ6OmNvdXQ8PCJDT05TVFJVQ1RFRFxuIjsgfQoJCX5UZXN0KCkgeyBzdGQ6OmNvdXQ8PCJERVNUUlVDVEVEXG4iOyB9CgkJCgkJdm9pZCBwcmludCgpCgkJewoJCQlzdGQ6OmNvdXQ8PHRoaXMtPndvcmQ8PCJcbiI7CgkJfQp9OwoKCmludCBtYWluKCkgewoKCXN0ZDo6dmVjdG9yPEhvbGRlcj4gY29udGFpbmVyOwoJY29udGFpbmVyLnB1c2hfYmFjayhIb2xkZXJ7Q1VTVE9NX1RZUEU6OkNIQVJfVFlQRSwgbmV3IGNoYXIoJ0EnKX0pOwoJY29udGFpbmVyLmVtcGxhY2VfYmFjayhIb2xkZXJ7Q1VTVE9NX1RZUEU6OkNIQVJfVFlQRSwgbmV3IGNoYXIoJ0InKX0pOwoJY29udGFpbmVyLmVtcGxhY2VfYmFjayhIb2xkZXJ7Q1VTVE9NX1RZUEU6OklOVF9UWVBFLCBuZXcgaW50KDEwMjQpfSk7Cgljb250YWluZXIuZW1wbGFjZV9iYWNrKEhvbGRlcntDVVNUT01fVFlQRTo6RkxPQVRfVFlQRSwgbmV3IGZsb2F0KDk4Ljk4Mzk3KX0pOwoJY29udGFpbmVyLmVtcGxhY2VfYmFjayhIb2xkZXJ7Q1VTVE9NX1RZUEU6OkRPVUJMRV9UWVBFLCBuZXcgZG91YmxlKDk5Ljk5NDI5OTk5OTcpfSk7Cgljb250YWluZXIuZW1wbGFjZV9iYWNrKEhvbGRlcntDVVNUT01fVFlQRTo6Q0xBU1NfVFlQRSwgbmV3IFRlc3QoIkhFTExPIil9KTsKCWNvbnRhaW5lci5lbXBsYWNlX2JhY2soSG9sZGVye0NVU1RPTV9UWVBFOjpDTEFTU19UWVBFLCBuZXcgVGVzdCgiV09STEQiKX0pOwoJCglmb3IgKEhvbGRlciAmaCA6IGNvbnRhaW5lcikKCXsKCQlzd2l0Y2goaC50eXBlKQoJCXsKCQkJY2FzZSBDVVNUT01fVFlQRTo6Q0hBUl9UWVBFOiB7CgkJCQlzdGQ6OmNvdXQ8PCpoLmdldDxjaGFyPigpPDwiXG4iOwoJCQl9CgkJCQlicmVhazsKCQkJCQoJCQljYXNlIENVU1RPTV9UWVBFOjpJTlRfVFlQRTogewoJCQkJc3RkOjpjb3V0PDwqaC5nZXQ8aW50PigpPDwiXG4iOwoJCQl9CgkJCQlicmVhazsKCQkJCQoJCQljYXNlIENVU1RPTV9UWVBFOjpGTE9BVF9UWVBFOiB7CgkJCQlzdGQ6OmNvdXQ8PCpoLmdldDxmbG9hdD4oKTw8IlxuIjsKCQkJfQoJCQkJYnJlYWs7CgkJCQkKCQkJY2FzZSBDVVNUT01fVFlQRTo6RE9VQkxFX1RZUEU6IHsKCQkJCXN0ZDo6Y291dDw8KmguZ2V0PGRvdWJsZT4oKTw8IlxuIjsKCQkJfQoJCQkJYnJlYWs7CgkJCQkKCQkJY2FzZSBDVVNUT01fVFlQRTo6Q0xBU1NfVFlQRTogewoJCQkJaC5nZXQ8VGVzdD4oKS0+cHJpbnQoKTsKCQkJfQoJCQkJYnJlYWs7CgkJfQoJfQoJCglyZXR1cm4gMDsKfQ==