#include <map>
#include <iostream>
using namespace std;
class A
{
public:
typedef A *creator();
typedef map<int,creator*> creatormap;
static creatormap &getmap()
{
static creatormap amap;
return amap;
}
template<class T> static void reg(int value)
{
getmap()[value]=[] () -> A* { return new T(); };
}
static A *make(int value)
{
creator *fun=getmap()[value];
return (fun?fun():0);
}
};
class B:public A
{
public:
B() { cout<<"B"<<endl; }
};
class C:public A
{
public:
C() { cout<<"C"<<endl; }
};
class D:public C
{
public:
D() { cout<<"D"<<endl; }
};
void reg()
{
A::reg<B>(1);
A::reg<C>(2);
A::reg<D>(3);
}
int main()
{
reg();
A *b=A::make(1);
A *c=A::make(2);
A *d=A::make(3);
A *a=A::make(0);
if(!a) cout<<"is NULL and it is OK"<<endl;
delete b;
delete c;
delete d;
return 0;
}
I2luY2x1ZGUgPG1hcD4KI2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKY2xhc3MgQQogIHsKICAgcHVibGljOgogICB0eXBlZGVmIEEgKmNyZWF0b3IoKTsKICAgdHlwZWRlZiBtYXA8aW50LGNyZWF0b3IqPiBjcmVhdG9ybWFwOwogICBzdGF0aWMgY3JlYXRvcm1hcCAmZ2V0bWFwKCkKICAgICB7CiAgICAgIHN0YXRpYyBjcmVhdG9ybWFwIGFtYXA7CQogICAgICByZXR1cm4gYW1hcDsKICAgICB9CiAgIHRlbXBsYXRlPGNsYXNzIFQ+IHN0YXRpYyB2b2lkIHJlZyhpbnQgdmFsdWUpCiAgICAgewogICAgICBnZXRtYXAoKVt2YWx1ZV09W10gKCkgLT4gQSogeyByZXR1cm4gbmV3IFQoKTsgfTsKICAgICB9CiAgIHN0YXRpYyBBICptYWtlKGludCB2YWx1ZSkKICAgICB7CiAgICAgIGNyZWF0b3IgKmZ1bj1nZXRtYXAoKVt2YWx1ZV07CiAgICAgIHJldHVybiAoZnVuP2Z1bigpOjApOwogICAgIH0KICB9OwogIApjbGFzcyBCOnB1YmxpYyBBCiAgewogICBwdWJsaWM6CiAgIEIoKSB7IGNvdXQ8PCJCIjw8ZW5kbDsgfQogIH07CgpjbGFzcyBDOnB1YmxpYyBBCiAgewogICBwdWJsaWM6CiAgIEMoKSB7IGNvdXQ8PCJDIjw8ZW5kbDsgfQogIH07CgpjbGFzcyBEOnB1YmxpYyBDCiAgewogICBwdWJsaWM6CiAgIEQoKSB7IGNvdXQ8PCJEIjw8ZW5kbDsgfQogIH07Cgp2b2lkIHJlZygpCiAgewogICBBOjpyZWc8Qj4oMSk7CiAgIEE6OnJlZzxDPigyKTsKICAgQTo6cmVnPEQ+KDMpOwogIH0KCmludCBtYWluKCkKICB7CiAgIHJlZygpOwogICBBICpiPUE6Om1ha2UoMSk7IAogICBBICpjPUE6Om1ha2UoMik7CiAgIEEgKmQ9QTo6bWFrZSgzKTsKICAgQSAqYT1BOjptYWtlKDApOwogICBpZighYSkgY291dDw8ImlzIE5VTEwgYW5kIGl0IGlzIE9LIjw8ZW5kbDsKICAgZGVsZXRlIGI7CiAgIGRlbGV0ZSBjOwogICBkZWxldGUgZDsKICAgcmV0dXJuIDA7CiAgfQ==