#include <unordered_map>
#include <string>
#include <iostream>
class Base
{
public:
typedef std::unordered_map<std::string, void*> registry_map;
virtual ~Base() = default;
static registry_map & registry()
{
static registry_map impl;
return impl;
}
template<typename ...T>
static Base * instantiate(std::string const & name, T&&...args)
{
auto it = registry().find(name);
if ( it == registry().end()) return 0;
typedef Base* (*create_type)(T...);
auto create_fun = reinterpret_cast<create_type>(it->second);
return create_fun(args...);
}
virtual void f() = 0;
};
struct Registrar
{
template<typename F>
Registrar(std::string name, F func)
{
Base::registry()[name] = reinterpret_cast<void*>(func);
}
};
class DerivedExample : public Base
{
static Registrar registrar;
public:
static Base * create() { return new DerivedExample; }
virtual void f() override { std::cout << "DerivedExample" << std::endl; }
};
Registrar DerivedExample::registrar("DerivedExample", DerivedExample::create);
class AnotherExample : public Base
{
static Registrar registrar;
int a;
const char *b;
public:
AnotherExample(int a, const char *b) : a(a), b(b) {}
static Base * create(int a, const char *b) { return new AnotherExample(a,b); }
virtual void f() override { std::cout << "AnotherExample. a = " << a << ", b = " << b << std::endl; }
};
Registrar AnotherExample::registrar("AnotherExample", AnotherExample::create);
int main()
{
Base * p = Base::instantiate("DerivedExample");
Base * q = Base::instantiate("AnotherExample", 10, "Mahfuza");
p->f();
q->f();
delete p;
delete q;
}
I2luY2x1ZGUgPHVub3JkZXJlZF9tYXA+CiNpbmNsdWRlIDxzdHJpbmc+CiNpbmNsdWRlIDxpb3N0cmVhbT4KCmNsYXNzIEJhc2UKewpwdWJsaWM6CiAgICB0eXBlZGVmIHN0ZDo6dW5vcmRlcmVkX21hcDxzdGQ6OnN0cmluZywgdm9pZCo+IHJlZ2lzdHJ5X21hcDsKCiAgICB2aXJ0dWFsIH5CYXNlKCkgPSBkZWZhdWx0OwoKICAgIHN0YXRpYyByZWdpc3RyeV9tYXAgJiByZWdpc3RyeSgpCiAgICB7CiAgICAgICAgc3RhdGljIHJlZ2lzdHJ5X21hcCBpbXBsOwoJICAgIHJldHVybiBpbXBsOwogICAgfQogICAgdGVtcGxhdGU8dHlwZW5hbWUgLi4uVD4KICAgIHN0YXRpYyBCYXNlICogaW5zdGFudGlhdGUoc3RkOjpzdHJpbmcgY29uc3QgJiBuYW1lLCBUJiYuLi5hcmdzKQogICAgewoJICAgIGF1dG8gaXQgPSByZWdpc3RyeSgpLmZpbmQobmFtZSk7CgkgICAgaWYgKCBpdCA9PSByZWdpc3RyeSgpLmVuZCgpKSByZXR1cm4gMDsKCSAgICB0eXBlZGVmIEJhc2UqICgqY3JlYXRlX3R5cGUpKFQuLi4pOwoJICAgIGF1dG8gY3JlYXRlX2Z1biA9IHJlaW50ZXJwcmV0X2Nhc3Q8Y3JlYXRlX3R5cGU+KGl0LT5zZWNvbmQpOwoJICAgIHJldHVybiBjcmVhdGVfZnVuKGFyZ3MuLi4pOwogICAgfQogICAgdmlydHVhbCB2b2lkIGYoKSA9IDA7Cn07CgpzdHJ1Y3QgUmVnaXN0cmFyCnsKCXRlbXBsYXRlPHR5cGVuYW1lIEY+CglSZWdpc3RyYXIoc3RkOjpzdHJpbmcgbmFtZSwgRiBmdW5jKQoJewoJCUJhc2U6OnJlZ2lzdHJ5KClbbmFtZV0gPSByZWludGVycHJldF9jYXN0PHZvaWQqPihmdW5jKTsKCX0KfTsKCmNsYXNzIERlcml2ZWRFeGFtcGxlIDogcHVibGljIEJhc2UKewogICAgc3RhdGljIFJlZ2lzdHJhciByZWdpc3RyYXI7CnB1YmxpYzoKICAgIHN0YXRpYyBCYXNlICogY3JlYXRlKCkgeyByZXR1cm4gbmV3IERlcml2ZWRFeGFtcGxlOyB9CiAgICB2aXJ0dWFsIHZvaWQgZigpIG92ZXJyaWRlIHsgc3RkOjpjb3V0IDw8ICJEZXJpdmVkRXhhbXBsZSIgPDwgc3RkOjplbmRsOyB9Cn07CgpSZWdpc3RyYXIgRGVyaXZlZEV4YW1wbGU6OnJlZ2lzdHJhcigiRGVyaXZlZEV4YW1wbGUiLCBEZXJpdmVkRXhhbXBsZTo6Y3JlYXRlKTsKCmNsYXNzIEFub3RoZXJFeGFtcGxlIDogcHVibGljIEJhc2UKewogICAgc3RhdGljIFJlZ2lzdHJhciByZWdpc3RyYXI7CiAgICBpbnQgYTsKICAgIGNvbnN0IGNoYXIgKmI7CnB1YmxpYzoKICAgIEFub3RoZXJFeGFtcGxlKGludCBhLCBjb25zdCBjaGFyICpiKSA6IGEoYSksIGIoYikge30KICAgIHN0YXRpYyBCYXNlICogY3JlYXRlKGludCBhLCBjb25zdCBjaGFyICpiKSB7IHJldHVybiBuZXcgQW5vdGhlckV4YW1wbGUoYSxiKTsgfQogICAgdmlydHVhbCB2b2lkIGYoKSBvdmVycmlkZSB7IHN0ZDo6Y291dCA8PCAiQW5vdGhlckV4YW1wbGUuIGEgPSAiIDw8IGEgPDwgIiwgYiA9ICIgPDwgYiA8PCBzdGQ6OmVuZGw7IH0KfTsKClJlZ2lzdHJhciBBbm90aGVyRXhhbXBsZTo6cmVnaXN0cmFyKCJBbm90aGVyRXhhbXBsZSIsIEFub3RoZXJFeGFtcGxlOjpjcmVhdGUpOwoKaW50IG1haW4oKQp7CglCYXNlICogcCA9IEJhc2U6Omluc3RhbnRpYXRlKCJEZXJpdmVkRXhhbXBsZSIpOwoJQmFzZSAqIHEgPSBCYXNlOjppbnN0YW50aWF0ZSgiQW5vdGhlckV4YW1wbGUiLCAxMCwgIk1haGZ1emEiKTsKCXAtPmYoKTsKCXEtPmYoKTsKICAgIAogICAgZGVsZXRlIHA7CiAgICBkZWxldGUgcTsKfQo=