#include <memory>
#include <string>
#include <unordered_map>
#include <iostream>
#include <cstdlib>
using namespace std;
struct Animal {
virtual void say(ostream &ostr) const = 0;
};
struct Dog: public Animal {
virtual void say(ostream &ostr) const {
ostr << "Bark!";
}
};
struct Cat: public Animal {
virtual void say(ostream &ostr) const {
ostr << "Meow!";
}
};
typedef unordered_map<string, unique_ptr<Animal>> AnimalMap;
static const char *ANIMAL_ENV = "ANIMAL";
static const char *ANIMAL_DEFAULT = "Dog";
int main(int, char const *[])
{
static const AnimalMap animal_map = []() {
AnimalMap res;
res.emplace("Dog", make_unique<Dog>());
res.emplace("Cat", make_unique<Cat>());
return res;
}();
const char *animal = getenv(ANIMAL_ENV);
if (animal == nullptr) {
animal = ANIMAL_DEFAULT;
}
auto hit = animal_map.find(animal);
if (hit != animal_map.cend()) {
hit->second->say(cout);
cout << endl;
} else {
cerr << "Error: Animal not found: " << animal << endl;
}
return 0;
}
I2luY2x1ZGUgPG1lbW9yeT4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPHVub3JkZXJlZF9tYXA+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPGNzdGRsaWI+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKCnN0cnVjdCBBbmltYWwgewoJdmlydHVhbCB2b2lkIHNheShvc3RyZWFtICZvc3RyKSBjb25zdCA9IDA7Cn07CgpzdHJ1Y3QgRG9nOiBwdWJsaWMgQW5pbWFsIHsKCXZpcnR1YWwgdm9pZCBzYXkob3N0cmVhbSAmb3N0cikgY29uc3QgewoJCW9zdHIgPDwgIkJhcmshIjsKCX0KfTsKCnN0cnVjdCBDYXQ6IHB1YmxpYyBBbmltYWwgewoJdmlydHVhbCB2b2lkIHNheShvc3RyZWFtICZvc3RyKSBjb25zdCB7CgkJb3N0ciA8PCAiTWVvdyEiOwoJfQp9OwoKdHlwZWRlZiB1bm9yZGVyZWRfbWFwPHN0cmluZywgdW5pcXVlX3B0cjxBbmltYWw+PiBBbmltYWxNYXA7CgpzdGF0aWMgY29uc3QgY2hhciAqQU5JTUFMX0VOViA9ICJBTklNQUwiOwpzdGF0aWMgY29uc3QgY2hhciAqQU5JTUFMX0RFRkFVTFQgPSAiRG9nIjsKCmludCBtYWluKGludCwgY2hhciBjb25zdCAqW10pCnsKCXN0YXRpYyBjb25zdCBBbmltYWxNYXAgYW5pbWFsX21hcCA9IFtdKCkgewoJCUFuaW1hbE1hcCByZXM7CgkJcmVzLmVtcGxhY2UoIkRvZyIsIG1ha2VfdW5pcXVlPERvZz4oKSk7CgkJcmVzLmVtcGxhY2UoIkNhdCIsIG1ha2VfdW5pcXVlPENhdD4oKSk7CgkJcmV0dXJuIHJlczsKCX0oKTsKCgljb25zdCBjaGFyICphbmltYWwgPSBnZXRlbnYoQU5JTUFMX0VOVik7CglpZiAoYW5pbWFsID09IG51bGxwdHIpIHsKCQlhbmltYWwgPSBBTklNQUxfREVGQVVMVDsKCX0KCglhdXRvIGhpdCA9IGFuaW1hbF9tYXAuZmluZChhbmltYWwpOwoJaWYgKGhpdCAhPSBhbmltYWxfbWFwLmNlbmQoKSkgewoJCWhpdC0+c2Vjb25kLT5zYXkoY291dCk7CgkJY291dCA8PCBlbmRsOwoJfSBlbHNlIHsKCQljZXJyIDw8ICJFcnJvcjogQW5pbWFsIG5vdCBmb3VuZDogIiA8PCBhbmltYWwgPDwgZW5kbDsKCX0KCglyZXR1cm4gMDsKfQo=