#include <iostream>
#include <vector>
#include <memory>
 
#define PROPERTY_TYPES \
    X(CAR, "A Car") \
    X(HOUSE, "A House") \
    X(ISLAND, "An Island") // <-- add more types
 
#define X(type, name) type, 
enum class property_type : size_t
{
	PROPERTY_TYPES
};
#undef X
 
#define X(type, name) name,
const char *property_name[] =
{
	PROPERTY_TYPES
};
#undef X
 
class Property
{
public:
	virtual property_type type() = 0;
};
 
class Car : public Property
{
public:
	Car(std::string name) : mName(name) {}
	std::string mName;
	property_type type() { return property_type::CAR; }
};
 
class House : public Property
{
public:
	House(std::string name) : mName(name) {}
	std::string mName;
	property_type type() { return property_type::HOUSE; }
};
 
class Person
{
public:
	std::vector< std::shared_ptr<Property> > properties;
};
 
std::ostream& operator<< (std::ostream& os, property_type type)
{
	os << property_name[static_cast<size_t>(type)];
	return os;
}
 
int main()
{
	Person x;
	auto y = std::shared_ptr<Property>(new Car("my car"));
	auto z = std::shared_ptr<Property>(new House("my house"));
	x.properties.push_back(y);
	x.properties.push_back(z);
	for (auto i : x.properties)
	{
		std::cout << i->type() << std::endl;
	}
	return 0;
}
				I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8bWVtb3J5PgoKI2RlZmluZSBQUk9QRVJUWV9UWVBFUyBcCiAgICBYKENBUiwgIkEgQ2FyIikgXAogICAgWChIT1VTRSwgIkEgSG91c2UiKSBcCiAgICBYKElTTEFORCwgIkFuIElzbGFuZCIpIC8vIDwtLSBhZGQgbW9yZSB0eXBlcwoKI2RlZmluZSBYKHR5cGUsIG5hbWUpIHR5cGUsIAplbnVtIGNsYXNzIHByb3BlcnR5X3R5cGUgOiBzaXplX3QKewoJUFJPUEVSVFlfVFlQRVMKfTsKI3VuZGVmIFgKCiNkZWZpbmUgWCh0eXBlLCBuYW1lKSBuYW1lLApjb25zdCBjaGFyICpwcm9wZXJ0eV9uYW1lW10gPQp7CglQUk9QRVJUWV9UWVBFUwp9OwojdW5kZWYgWAoKY2xhc3MgUHJvcGVydHkKewpwdWJsaWM6Cgl2aXJ0dWFsIHByb3BlcnR5X3R5cGUgdHlwZSgpID0gMDsKfTsKCmNsYXNzIENhciA6IHB1YmxpYyBQcm9wZXJ0eQp7CnB1YmxpYzoKCUNhcihzdGQ6OnN0cmluZyBuYW1lKSA6IG1OYW1lKG5hbWUpIHt9CglzdGQ6OnN0cmluZyBtTmFtZTsKCXByb3BlcnR5X3R5cGUgdHlwZSgpIHsgcmV0dXJuIHByb3BlcnR5X3R5cGU6OkNBUjsgfQp9OwoKY2xhc3MgSG91c2UgOiBwdWJsaWMgUHJvcGVydHkKewpwdWJsaWM6CglIb3VzZShzdGQ6OnN0cmluZyBuYW1lKSA6IG1OYW1lKG5hbWUpIHt9CglzdGQ6OnN0cmluZyBtTmFtZTsKCXByb3BlcnR5X3R5cGUgdHlwZSgpIHsgcmV0dXJuIHByb3BlcnR5X3R5cGU6OkhPVVNFOyB9Cn07CgpjbGFzcyBQZXJzb24KewpwdWJsaWM6CglzdGQ6OnZlY3Rvcjwgc3RkOjpzaGFyZWRfcHRyPFByb3BlcnR5PiA+IHByb3BlcnRpZXM7Cn07CgpzdGQ6Om9zdHJlYW0mIG9wZXJhdG9yPDwgKHN0ZDo6b3N0cmVhbSYgb3MsIHByb3BlcnR5X3R5cGUgdHlwZSkKewoJb3MgPDwgcHJvcGVydHlfbmFtZVtzdGF0aWNfY2FzdDxzaXplX3Q+KHR5cGUpXTsKCXJldHVybiBvczsKfQoKaW50IG1haW4oKQp7CglQZXJzb24geDsKCWF1dG8geSA9IHN0ZDo6c2hhcmVkX3B0cjxQcm9wZXJ0eT4obmV3IENhcigibXkgY2FyIikpOwoJYXV0byB6ID0gc3RkOjpzaGFyZWRfcHRyPFByb3BlcnR5PihuZXcgSG91c2UoIm15IGhvdXNlIikpOwoJeC5wcm9wZXJ0aWVzLnB1c2hfYmFjayh5KTsKCXgucHJvcGVydGllcy5wdXNoX2JhY2soeik7Cglmb3IgKGF1dG8gaSA6IHgucHJvcGVydGllcykKCXsKCQlzdGQ6OmNvdXQgPDwgaS0+dHlwZSgpIDw8IHN0ZDo6ZW5kbDsKCX0KCXJldHVybiAwOwp9