#include <iostream>
#include <functional>
#include <map>
#include <typeinfo>
#include <memory>
using namespace std;
struct IAnimal;
struct AnimalFactory
{
using FactoryFunction = std::function<IAnimal*(std::string)>;
bool RegisterFunction(std::string name, FactoryFunction f)
{
factoryMap.insert(std::make_pair(name,f));
return true;
}
std::unique_ptr<IAnimal> CreateAnimal(std::string name, std::string xml)
{
return std::unique_ptr<IAnimal>(factoryMap.at(name)(xml));
}
static AnimalFactory &instance()
{
static AnimalFactory factory{};
return factory;
}
private:
std::map<std::string, FactoryFunction> factoryMap;
};
struct IAnimal{virtual ~IAnimal(){}};
struct Cat : IAnimal
{
Cat (std::string xml) {}
static Cat* CreateAnimal(std::string xml) { return new Cat(xml); }
static bool registered;
};
bool Cat::registered = AnimalFactory::instance().RegisterFunction("cat", Cat::CreateAnimal);
struct Elephant : IAnimal
{
Elephant (std::string xml) {}
static Elephant* CreateAnimal(std::string xml) { return new Elephant(xml); }
static bool registered;
};
bool Elephant::registered = AnimalFactory::instance().RegisterFunction("elephant", Elephant::CreateAnimal);
int main()
{
auto cat = AnimalFactory::instance().CreateAnimal("cat","hi");
auto elephant = AnimalFactory::instance().CreateAnimal("elephant","hi");
std::cout << typeid(*cat).name() << std::endl;
std::cout << typeid(*elephant).name() << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KI2luY2x1ZGUgPG1hcD4KI2luY2x1ZGUgPHR5cGVpbmZvPgojaW5jbHVkZSA8bWVtb3J5Pgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKc3RydWN0IElBbmltYWw7CnN0cnVjdCBBbmltYWxGYWN0b3J5CnsKICAgIHVzaW5nIEZhY3RvcnlGdW5jdGlvbiA9IHN0ZDo6ZnVuY3Rpb248SUFuaW1hbCooc3RkOjpzdHJpbmcpPjsKICAgIGJvb2wgUmVnaXN0ZXJGdW5jdGlvbihzdGQ6OnN0cmluZyBuYW1lLCBGYWN0b3J5RnVuY3Rpb24gZikKICAgIHsKICAgICAgICBmYWN0b3J5TWFwLmluc2VydChzdGQ6Om1ha2VfcGFpcihuYW1lLGYpKTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIHN0ZDo6dW5pcXVlX3B0cjxJQW5pbWFsPiBDcmVhdGVBbmltYWwoc3RkOjpzdHJpbmcgbmFtZSwgc3RkOjpzdHJpbmcgeG1sKQogICAgewogICAgICAgIHJldHVybiBzdGQ6OnVuaXF1ZV9wdHI8SUFuaW1hbD4oZmFjdG9yeU1hcC5hdChuYW1lKSh4bWwpKTsKICAgIH0KICAgIHN0YXRpYyBBbmltYWxGYWN0b3J5ICZpbnN0YW5jZSgpCiAgICB7CiAgICAgICAgc3RhdGljIEFuaW1hbEZhY3RvcnkgZmFjdG9yeXt9OwogICAgICAgIHJldHVybiBmYWN0b3J5OwogICAgfQoKcHJpdmF0ZToKICAgIHN0ZDo6bWFwPHN0ZDo6c3RyaW5nLCBGYWN0b3J5RnVuY3Rpb24+IGZhY3RvcnlNYXA7Cgp9OwoKc3RydWN0IElBbmltYWx7dmlydHVhbCB+SUFuaW1hbCgpe319OwoKc3RydWN0IENhdCA6IElBbmltYWwKewogICAgQ2F0IChzdGQ6OnN0cmluZyB4bWwpIHt9CiAgICBzdGF0aWMgQ2F0KiBDcmVhdGVBbmltYWwoc3RkOjpzdHJpbmcgeG1sKSB7IHJldHVybiBuZXcgQ2F0KHhtbCk7IH0KICAgIHN0YXRpYyBib29sIHJlZ2lzdGVyZWQ7Cn07CmJvb2wgQ2F0OjpyZWdpc3RlcmVkID0gQW5pbWFsRmFjdG9yeTo6aW5zdGFuY2UoKS5SZWdpc3RlckZ1bmN0aW9uKCJjYXQiLCBDYXQ6OkNyZWF0ZUFuaW1hbCk7CgpzdHJ1Y3QgRWxlcGhhbnQgOiBJQW5pbWFsCnsKICAgIEVsZXBoYW50IChzdGQ6OnN0cmluZyB4bWwpIHt9CiAgICBzdGF0aWMgRWxlcGhhbnQqIENyZWF0ZUFuaW1hbChzdGQ6OnN0cmluZyB4bWwpIHsgcmV0dXJuIG5ldyBFbGVwaGFudCh4bWwpOyB9CiAgICBzdGF0aWMgYm9vbCByZWdpc3RlcmVkOwp9Owpib29sIEVsZXBoYW50OjpyZWdpc3RlcmVkID0gQW5pbWFsRmFjdG9yeTo6aW5zdGFuY2UoKS5SZWdpc3RlckZ1bmN0aW9uKCJlbGVwaGFudCIsIEVsZXBoYW50OjpDcmVhdGVBbmltYWwpOwoKCgppbnQgbWFpbigpCnsKICAgIGF1dG8gY2F0ID0gQW5pbWFsRmFjdG9yeTo6aW5zdGFuY2UoKS5DcmVhdGVBbmltYWwoImNhdCIsImhpIik7CiAgICBhdXRvIGVsZXBoYW50ID0gQW5pbWFsRmFjdG9yeTo6aW5zdGFuY2UoKS5DcmVhdGVBbmltYWwoImVsZXBoYW50IiwiaGkiKTsKCiAgICBzdGQ6OmNvdXQgPDwgdHlwZWlkKCpjYXQpLm5hbWUoKSA8PCBzdGQ6OmVuZGw7CiAgICBzdGQ6OmNvdXQgPDwgdHlwZWlkKCplbGVwaGFudCkubmFtZSgpIDw8IHN0ZDo6ZW5kbDsKfQo=