#include <iostream>
#include <vector>
#include <memory>
using namespace std;
struct BaseComponent
{
template <typename T>
T * as()
{
return dynamic_cast<T*>(this);
}
virtual ~BaseComponent() {}
};
template <typename T>
struct Component : public BaseComponent
{
virtual ~Component() {}
};
struct PositionComponent : public Component<PositionComponent>
{
float x, y, z;
virtual ~PositionComponent() {}
};
struct AnotherComponent : public Component<AnotherComponent>
{
virtual ~AnotherComponent () {}
};
int main()
{
std::vector<std::unique_ptr<BaseComponent>> mComponents;
mComponents.emplace_back(new AnotherComponent);
auto *pos = mComponents[0]->as<PositionComponent>();
if (pos) {
pos->x = 1337;
} else {
cerr << "Not a PositionComponent." << endl;
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8bWVtb3J5PgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnN0cnVjdCBCYXNlQ29tcG9uZW50CnsKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBUPgogICAgVCAqIGFzKCkKICAgIHsKICAgICAgICByZXR1cm4gZHluYW1pY19jYXN0PFQqPih0aGlzKTsKICAgIH0KCiAgICB2aXJ0dWFsIH5CYXNlQ29tcG9uZW50KCkge30KfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdHJ1Y3QgQ29tcG9uZW50IDogcHVibGljIEJhc2VDb21wb25lbnQKewogICAgdmlydHVhbCB+Q29tcG9uZW50KCkge30KfTsKCnN0cnVjdCBQb3NpdGlvbkNvbXBvbmVudCA6IHB1YmxpYyBDb21wb25lbnQ8UG9zaXRpb25Db21wb25lbnQ+CnsKICAgIGZsb2F0IHgsIHksIHo7CgogICAgdmlydHVhbCB+UG9zaXRpb25Db21wb25lbnQoKSB7fQp9OwoKc3RydWN0IEFub3RoZXJDb21wb25lbnQgOiBwdWJsaWMgQ29tcG9uZW50PEFub3RoZXJDb21wb25lbnQ+CnsKICAgIHZpcnR1YWwgfkFub3RoZXJDb21wb25lbnQgKCkge30KfTsKCmludCBtYWluKCkKewogICAgc3RkOjp2ZWN0b3I8c3RkOjp1bmlxdWVfcHRyPEJhc2VDb21wb25lbnQ+PiBtQ29tcG9uZW50czsKICAgIG1Db21wb25lbnRzLmVtcGxhY2VfYmFjayhuZXcgQW5vdGhlckNvbXBvbmVudCk7CgogICAgYXV0byAqcG9zID0gbUNvbXBvbmVudHNbMF0tPmFzPFBvc2l0aW9uQ29tcG9uZW50PigpOwogICAgaWYgKHBvcykgewogICAgICAgIHBvcy0+eCA9IDEzMzc7CiAgICB9IGVsc2UgewogICAgICAgIGNlcnIgPDwgIk5vdCBhIFBvc2l0aW9uQ29tcG9uZW50LiIgPDwgZW5kbDsKICAgIH0KCiAgICByZXR1cm4gMDsKfQ==