#include <vector>
#include <iostream>
#include <typeinfo>

#define in :
#define let auto

class ComponentBase {
public:
    using ComId = unsigned int;

    ComponentBase() { }
    virtual ~ComponentBase() { }

    virtual auto printComponentInfo()   -> void  = 0;
    virtual auto getComponentType()     -> ComId = 0;
private:

};

class Render : public ComponentBase {
public:
    Render() { }

    virtual auto printComponentInfo() -> void;
    virtual auto getComponentType() -> ComId;
private:
};

auto Render::printComponentInfo() -> void {
    std::cout<<"Render component"<<std::endl;
}

auto Render::getComponentType() -> ComId {
    return 0;
}

class Transform : public ComponentBase {
public:
    Transform() { }

    virtual auto printComponentInfo() -> void;
    virtual auto getComponentType() -> ComId;
private:
};

auto Transform::printComponentInfo() -> void {
    std::cout<<"Transform component"<<std::endl;
}

auto Transform::getComponentType() -> ComId {
    return 1;
}

class GameObject {
public:
    GameObject() { }
    virtual ~GameObject() { }

    template <class T>
    auto addComponent() -> void;
   
    template <class T>
    auto getComponent() -> T*;

private:
    std::vector<ComponentBase*> components;
};

template <class T>
auto GameObject::addComponent() -> void {
    this->components.push_back(new T);
    std::cout<<typeid(T).name()<<std::endl;
}

template <class T>
auto GameObject::getComponent() -> T* {
    auto t = new T;

    for(auto com in this->components) {
        if(t->getComponentType() == com->getComponentType()) {
            return dynamic_cast<T*>(com);
        }
        else {
            com->printComponentInfo();
        }
    }

    return nullptr;
}

auto main(int argc, char* argv[]) -> int {
    let go = new GameObject();
   
    go->addComponent<Render>();
    go->addComponent<Transform>();

    let trans = go->getComponent<Transform>();

    if(trans == nullptr) std::cout<<"Couldn't find component!"<<std::endl;
    else trans->printComponentInfo();

    return 0;
}


 많이 ㅄ같긴한데 일단 되긴함. 순수하게 rtti를 이용해서 구현해보고 싶었는데, 컨테이너에 등록 된 타입따라 타입 정보가 나오니까 대충 대충 만들어서는 어케 할 지는 몰?루겠네.