#include <iostream>
#include <cstring>
#include <memory>
struct Base { virtual const char *getName() = 0; virtual ~Base() = default; };
struct SE_0 : Base { virtual const char *getName() override { return "SE_0"; } };
struct SE_1 : Base { virtual const char *getName() override { return "SE_1"; } };
struct SE_2 : Base { virtual const char *getName() override { return "SE_2"; } };
enum TypesEnum {
E__BEGIN = 0,
E_0 = E__BEGIN,
E_1,
E_2,
E__END
};
template<TypesEnum>
struct Registry {};
template<>
struct Registry<E_0> {
static constexpr const char *name = "The first type (SE_0)";
using type = SE_0;
};
template<>
struct Registry<E_1> {
static constexpr const char *name = "A second type (SE_1)";
using type = SE_1;
};
template<>
struct Registry<E_2> {
static constexpr const char *name = "And the last type (SE_2)";
using type = SE_2;
};
template<TypesEnum CurrentType>
std::unique_ptr<Base> createTypeImpl(const char *name)
{
if constexpr (CurrentType < E__END) {
if (strstr(Registry<CurrentType>::name, name)) {
return std::make_unique<typename Registry<CurrentType>::type>();
}
return createTypeImpl<static_cast<TypesEnum>(CurrentType + 1)>(name);
} else {
(void)name; // Silence 'unreferenced formal parameter' warning
return nullptr;
}
}
std::unique_ptr<Base> createType(const char *name)
{
return createTypeImpl<E__BEGIN>(name);
}
int main()
{
std::cout << "first type: " << createType("first type")->getName() << std::endl;
std::cout << "second type: " << createType("second type")->getName() << std::endl;
std::cout << "last type: " << createType("last type")->getName() << std::endl;
return EXIT_SUCCESS;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8Y3N0cmluZz4KI2luY2x1ZGUgPG1lbW9yeT4KCnN0cnVjdCBCYXNlIHsgdmlydHVhbCBjb25zdCBjaGFyICpnZXROYW1lKCkgPSAwOyB2aXJ0dWFsIH5CYXNlKCkgPSBkZWZhdWx0OyB9OwpzdHJ1Y3QgU0VfMCA6IEJhc2UgeyB2aXJ0dWFsIGNvbnN0IGNoYXIgKmdldE5hbWUoKSBvdmVycmlkZSB7IHJldHVybiAiU0VfMCI7IH0gfTsKc3RydWN0IFNFXzEgOiBCYXNlIHsgdmlydHVhbCBjb25zdCBjaGFyICpnZXROYW1lKCkgb3ZlcnJpZGUgeyByZXR1cm4gIlNFXzEiOyB9IH07CnN0cnVjdCBTRV8yIDogQmFzZSB7IHZpcnR1YWwgY29uc3QgY2hhciAqZ2V0TmFtZSgpIG92ZXJyaWRlIHsgcmV0dXJuICJTRV8yIjsgfSB9OwoKZW51bSBUeXBlc0VudW0gewogICAgRV9fQkVHSU4gPSAwLAoKICAgIEVfMCA9IEVfX0JFR0lOLAogICAgRV8xLAogICAgRV8yLAoKICAgIEVfX0VORAp9OwoKdGVtcGxhdGU8VHlwZXNFbnVtPgpzdHJ1Y3QgUmVnaXN0cnkge307Cgp0ZW1wbGF0ZTw+CnN0cnVjdCBSZWdpc3RyeTxFXzA+IHsKICAgIHN0YXRpYyBjb25zdGV4cHIgY29uc3QgY2hhciAqbmFtZSA9ICJUaGUgZmlyc3QgdHlwZSAoU0VfMCkiOwogICAgdXNpbmcgdHlwZSA9IFNFXzA7Cn07Cgp0ZW1wbGF0ZTw+CnN0cnVjdCBSZWdpc3RyeTxFXzE+IHsKICAgIHN0YXRpYyBjb25zdGV4cHIgY29uc3QgY2hhciAqbmFtZSA9ICJBIHNlY29uZCB0eXBlIChTRV8xKSI7CiAgICB1c2luZyB0eXBlID0gU0VfMTsKfTsKCnRlbXBsYXRlPD4Kc3RydWN0IFJlZ2lzdHJ5PEVfMj4gewogICAgc3RhdGljIGNvbnN0ZXhwciBjb25zdCBjaGFyICpuYW1lID0gIkFuZCB0aGUgbGFzdCB0eXBlIChTRV8yKSI7CiAgICB1c2luZyB0eXBlID0gU0VfMjsKfTsKCnRlbXBsYXRlPFR5cGVzRW51bSBDdXJyZW50VHlwZT4Kc3RkOjp1bmlxdWVfcHRyPEJhc2U+IGNyZWF0ZVR5cGVJbXBsKGNvbnN0IGNoYXIgKm5hbWUpCnsKICAgIGlmIGNvbnN0ZXhwciAoQ3VycmVudFR5cGUgPCBFX19FTkQpIHsKICAgICAgICBpZiAoc3Ryc3RyKFJlZ2lzdHJ5PEN1cnJlbnRUeXBlPjo6bmFtZSwgbmFtZSkpIHsKICAgICAgICAgICAgcmV0dXJuIHN0ZDo6bWFrZV91bmlxdWU8dHlwZW5hbWUgUmVnaXN0cnk8Q3VycmVudFR5cGU+Ojp0eXBlPigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY3JlYXRlVHlwZUltcGw8c3RhdGljX2Nhc3Q8VHlwZXNFbnVtPihDdXJyZW50VHlwZSArIDEpPihuYW1lKTsKICAgIH0gZWxzZSB7CiAgICAgICAgKHZvaWQpbmFtZTsgIC8vIFNpbGVuY2UgJ3VucmVmZXJlbmNlZCBmb3JtYWwgcGFyYW1ldGVyJyB3YXJuaW5nCiAgICAgICAgcmV0dXJuIG51bGxwdHI7CiAgICB9Cn0KCnN0ZDo6dW5pcXVlX3B0cjxCYXNlPiBjcmVhdGVUeXBlKGNvbnN0IGNoYXIgKm5hbWUpCnsKICAgIHJldHVybiBjcmVhdGVUeXBlSW1wbDxFX19CRUdJTj4obmFtZSk7Cn0KCmludCBtYWluKCkKewogICAgc3RkOjpjb3V0IDw8ICJmaXJzdCB0eXBlOiAiIDw8IGNyZWF0ZVR5cGUoImZpcnN0IHR5cGUiKS0+Z2V0TmFtZSgpIDw8IHN0ZDo6ZW5kbDsKICAgIHN0ZDo6Y291dCA8PCAic2Vjb25kIHR5cGU6ICIgPDwgY3JlYXRlVHlwZSgic2Vjb25kIHR5cGUiKS0+Z2V0TmFtZSgpIDw8IHN0ZDo6ZW5kbDsKICAgIHN0ZDo6Y291dCA8PCAibGFzdCB0eXBlOiAiIDw8IGNyZWF0ZVR5cGUoImxhc3QgdHlwZSIpLT5nZXROYW1lKCkgPDwgc3RkOjplbmRsOwoKICAgIHJldHVybiBFWElUX1NVQ0NFU1M7Cn0KCg==