#include <iostream>
#include <string>
#include <map>
#include <memory>
struct One;
struct Two;
struct Three;
struct Number {
virtual ~Number() {}
virtual void f() = 0;
static Number* getByName(const std::string &name) {
static const std::map<std::string, std::function<Number*()>> factories = {
register_helper<One>(),
register_helper<Two>(),
register_helper<Three>()
};
auto it = factories.find(name);
if (it == factories.end()) {
return nullptr;
} else {
return it->second();
}
}
private:
template <typename T>
static std::pair<std::string, std::function<Number*()>> register_helper()
{
return { T::name, []() { return new T{}; }};
}
};
struct One : Number {
virtual void f() override { std::cout << "ONE" << std::endl; }
const static std::string name;
};
struct Two : Number {
virtual void f() override { std::cout << "TWO" << std::endl; }
const static std::string name;
};
struct Three : Number {
virtual void f() override { std::cout << "THREE" << std::endl; }
const static std::string name;
};
const std::string One::name = "one";
const std::string Two::name = "two";
const std::string Three::name = "three";
int main() {
std::unique_ptr<Number> two(Number::getByName("two"));
two->f();
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8bWFwPgojaW5jbHVkZSA8bWVtb3J5PgoKc3RydWN0IE9uZTsKc3RydWN0IFR3bzsKc3RydWN0IFRocmVlOwoKc3RydWN0IE51bWJlciB7CiAgICB2aXJ0dWFsIH5OdW1iZXIoKSB7fQogICAgdmlydHVhbCB2b2lkIGYoKSA9IDA7CgoJc3RhdGljIE51bWJlciogZ2V0QnlOYW1lKGNvbnN0IHN0ZDo6c3RyaW5nICZuYW1lKSB7CgkgICAgc3RhdGljIGNvbnN0IHN0ZDo6bWFwPHN0ZDo6c3RyaW5nLCBzdGQ6OmZ1bmN0aW9uPE51bWJlciooKT4+IGZhY3RvcmllcyA9IHsKCSAgICAgICAgIHJlZ2lzdGVyX2hlbHBlcjxPbmU+KCksCgkgICAgICAgICByZWdpc3Rlcl9oZWxwZXI8VHdvPigpLAoJICAgICAgICAgcmVnaXN0ZXJfaGVscGVyPFRocmVlPigpCgkgICAgfTsKCQoJICAgIGF1dG8gaXQgPSBmYWN0b3JpZXMuZmluZChuYW1lKTsKCSAgICBpZiAoaXQgPT0gZmFjdG9yaWVzLmVuZCgpKSB7CgkgICAgICAgIHJldHVybiBudWxscHRyOwoJICAgIH0gZWxzZSB7CgkgICAgICAgIHJldHVybiBpdC0+c2Vjb25kKCk7CgkgICAgfQoJfQpwcml2YXRlOgoJdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CglzdGF0aWMgc3RkOjpwYWlyPHN0ZDo6c3RyaW5nLCBzdGQ6OmZ1bmN0aW9uPE51bWJlciooKT4+IHJlZ2lzdGVyX2hlbHBlcigpCgl7CgkgICAgcmV0dXJuIHsgVDo6bmFtZSwgW10oKSB7IHJldHVybiBuZXcgVHt9OyB9fTsKCX0KCn07CgpzdHJ1Y3QgT25lIDogTnVtYmVyIHsKICAgIHZpcnR1YWwgdm9pZCBmKCkgb3ZlcnJpZGUgeyBzdGQ6OmNvdXQgPDwgIk9ORSIgPDwgc3RkOjplbmRsOyB9CiAgICBjb25zdCBzdGF0aWMgc3RkOjpzdHJpbmcgbmFtZTsKfTsKCnN0cnVjdCBUd28gOiBOdW1iZXIgewogICAgdmlydHVhbCB2b2lkIGYoKSBvdmVycmlkZSB7IHN0ZDo6Y291dCA8PCAiVFdPIiA8PCBzdGQ6OmVuZGw7IH0KICAgIGNvbnN0IHN0YXRpYyBzdGQ6OnN0cmluZyBuYW1lOwp9OwoKc3RydWN0IFRocmVlIDogTnVtYmVyIHsKICAgIHZpcnR1YWwgdm9pZCBmKCkgb3ZlcnJpZGUgeyBzdGQ6OmNvdXQgPDwgIlRIUkVFIiA8PCBzdGQ6OmVuZGw7IH0KICAgIGNvbnN0IHN0YXRpYyBzdGQ6OnN0cmluZyBuYW1lOwp9OwoKY29uc3Qgc3RkOjpzdHJpbmcgT25lOjpuYW1lID0gIm9uZSI7CmNvbnN0IHN0ZDo6c3RyaW5nIFR3bzo6bmFtZSA9ICJ0d28iOwpjb25zdCBzdGQ6OnN0cmluZyBUaHJlZTo6bmFtZSA9ICJ0aHJlZSI7CgppbnQgbWFpbigpIHsKICAgIHN0ZDo6dW5pcXVlX3B0cjxOdW1iZXI+IHR3byhOdW1iZXI6OmdldEJ5TmFtZSgidHdvIikpOwogICAgdHdvLT5mKCk7Cn0K