#include<map>
#include<string>
#include<iostream>
using namespace std;
struct IFoo{};
struct Factory
{
struct Base{ virtual IFoo * build()const=0; };
typedef std::string Str;
typedef std::map<const Str, Base*> Map;
typedef Map::const_iterator It;
typedef Map::value_type ValType;
template<class T> struct Builder : Base
{
IFoo* build()const { return new T; };
};
template<class T> static void reg_class(const Str& key)
{
reg().insert( ValType(key, new Builder<T>()) );
}
static IFoo* build(const Str& key)
{
It it = reg().find(key);
return (it==reg().end())? 0l : it->second->build() ;
}
private:
static std::map<const Str, Base*>& reg(){ static Map data; return data; }
};
struct Bar0 : IFoo
{
Bar0(){ cout<<"i am Bar0\n"; }
};
struct Bar1 : IFoo
{
Bar1(){ cout<<"i am Bar1\n"; }
};
int main()
{
Factory::reg_class<Bar0>("Bar0");
Factory::reg_class<Bar1>("Bar1");
//---------
IFoo* ptr = Factory::build("Bar0");
}
I2luY2x1ZGU8bWFwPgojaW5jbHVkZTxzdHJpbmc+CiNpbmNsdWRlPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwogCnN0cnVjdCBJRm9ve307CgpzdHJ1Y3QgRmFjdG9yeQp7CiAgc3RydWN0IEJhc2V7IHZpcnR1YWwgSUZvbyAqIGJ1aWxkKCljb25zdD0wOyAgfTsKICAKICB0eXBlZGVmIHN0ZDo6c3RyaW5nIFN0cjsKICB0eXBlZGVmIHN0ZDo6bWFwPGNvbnN0IFN0ciwgQmFzZSo+IE1hcDsKICB0eXBlZGVmIE1hcDo6Y29uc3RfaXRlcmF0b3IgSXQ7CiAgdHlwZWRlZiBNYXA6OnZhbHVlX3R5cGUgVmFsVHlwZTsKIAogIHRlbXBsYXRlPGNsYXNzIFQ+IHN0cnVjdCBCdWlsZGVyIDogQmFzZQogIHsgCiAgICBJRm9vKiBidWlsZCgpY29uc3QgeyByZXR1cm4gbmV3IFQ7IH07ICAKICB9OwogCiAgdGVtcGxhdGU8Y2xhc3MgVD4gc3RhdGljIHZvaWQgcmVnX2NsYXNzKGNvbnN0IFN0ciYga2V5KQogIHsKICAgICAgcmVnKCkuaW5zZXJ0KCBWYWxUeXBlKGtleSwgbmV3IEJ1aWxkZXI8VD4oKSkgICk7ICAKICB9CiAKICBzdGF0aWMgSUZvbyogYnVpbGQoY29uc3QgU3RyJiBrZXkpIAogIHsKICAgICAgSXQgaXQgPSByZWcoKS5maW5kKGtleSk7CiAgICAgIHJldHVybiAoaXQ9PXJlZygpLmVuZCgpKT8gMGwgOiBpdC0+c2Vjb25kLT5idWlsZCgpIDsKICB9CnByaXZhdGU6CiAgc3RhdGljIHN0ZDo6bWFwPGNvbnN0IFN0ciwgQmFzZSo+JiByZWcoKXsgc3RhdGljIE1hcCBkYXRhOyByZXR1cm4gZGF0YTsgfQoKfTsKCnN0cnVjdCBCYXIwIDogSUZvbwp7CiAgICBCYXIwKCl7IGNvdXQ8PCJpIGFtIEJhcjBcbiI7IH0KfTsKc3RydWN0IEJhcjEgOiBJRm9vCnsKICAgIEJhcjEoKXsgY291dDw8ImkgYW0gQmFyMVxuIjsgfQp9OwoKaW50IG1haW4oKQp7CiAgICBGYWN0b3J5OjpyZWdfY2xhc3M8QmFyMD4oIkJhcjAiKTsKICAgIEZhY3Rvcnk6OnJlZ19jbGFzczxCYXIxPigiQmFyMSIpOwogICAgCiAgICAvLy0tLS0tLS0tLQoKICAgIElGb28qIHB0ciA9IEZhY3Rvcnk6OmJ1aWxkKCJCYXIwIik7Cn0=