Skip to content

Instantly share code, notes, and snippets.

@skyrpex
Last active October 13, 2015 14:30
Show Gist options
  • Select an option

  • Save skyrpex/2c45b9d8cc4c2c15a375 to your computer and use it in GitHub Desktop.

Select an option

Save skyrpex/2c45b9d8cc4c2c15a375 to your computer and use it in GitHub Desktop.

Revisions

  1. skyrpex revised this gist Oct 13, 2015. 1 changed file with 66 additions and 40 deletions.
    106 changes: 66 additions & 40 deletions ioc.cpp
    Original file line number Diff line number Diff line change
    @@ -5,76 +5,102 @@
    #include <memory>
    #include <unordered_map>

    class Test
    class AbstractTest
    {
    public:
    void log()
    virtual void yeah()
    {
    std::cout << "I'm Test! " << typeid(Test).name() << std::endl;
    std::cout << "I'm AbstractTest! " << typeid(AbstractTest).name() << std::endl;
    }
    };

    class Test2
    class Test : public AbstractTest
    {
    public:
    void log()
    void yeah() override
    {
    std::cout << "I'm Test2! " << typeid(Test).name() << std::endl;
    log();
    }
    };

    class AbstractInstance
    {
    void log()
    {
    std::cout << "I'm Test! " << typeid(Test).name() << std::endl;
    }
    };

    template<typename T>
    class Instance : public AbstractInstance
    class Test2 : public AbstractTest
    {
    public:
    Instance(T *ptr) : ptr(ptr) {}
    std::shared_ptr<T> ptr;
    void log()
    {
    std::cout << "I'm Test2! " << typeid(Test).name() << std::endl;
    }
    };

    class Container
    namespace ioc
    {
    public:
    template<typename T>
    void registerType(std::function<T * ()> callback)
    class Container
    {
    m_callbacks[std::type_index(typeid(T))] = callback;
    }
    public:
    class AbstractInstance
    {
    public:
    virtual ~AbstractInstance() {}
    };

    template<typename T>
    std::shared_ptr<T> make()
    {
    auto type = std::type_index(typeid(T));
    template<typename T>
    class Instance : public AbstractInstance
    {
    public:
    Instance(T *ptr) : ptr(ptr) {}
    std::shared_ptr<T> ptr;
    };

    auto search = m_instances.find(type);
    if (search != m_instances.end()) {
    auto instance = std::static_pointer_cast<Instance<T>>(search->second);
    return instance->ptr;
    template<typename T>
    void registerType(std::function<T * ()> callback)
    {
    m_callbacks[std::type_index(typeid(T))] = callback;
    }

    void *ptr = m_callbacks[type]();
    auto instance = std::make_shared<Instance<T>>(static_cast<T *>(ptr));
    m_instances[type] = instance;
    return instance->ptr;
    }
    template<typename T>
    std::shared_ptr<T> make()
    {
    auto type = std::type_index(typeid(T));

    protected:
    std::unordered_map<std::type_index, std::function<void * ()>> m_callbacks;
    std::unordered_map<std::type_index, std::shared_ptr<AbstractInstance>> m_instances;
    };
    auto search = m_instances.find(type);
    if (search != m_instances.end()) {
    auto instance = std::static_pointer_cast<Instance<T>>(search->second);
    return instance->ptr;
    }

    void *ptr = m_callbacks[type]();
    auto instance = std::make_shared<Instance<T>>(static_cast<T *>(ptr));
    m_instances[type] = instance;
    return instance->ptr;
    }

    protected:
    std::unordered_map<std::type_index, std::function<void * ()>> m_callbacks;
    std::unordered_map<std::type_index, std::shared_ptr<AbstractInstance>> m_instances;
    };
    }

    int main()
    {
    Container container;
    container.registerType<Test>([]() {
    ioc::Container container;
    container.registerType<AbstractTest>([]() {
    return new Test();
    });
    // container.registerType<Test2>([]() {
    // return new Test2();
    // });

    auto test = container.make<AbstractTest>();
    // test->log();
    test->yeah();

    auto test = container.make<Test>();
    test->log();
    // auto test2 = container.make<Test>();
    // std::cout << (test == test2) << std::endl;

    return 0;
    }
  2. skyrpex created this gist Oct 13, 2015.
    80 changes: 80 additions & 0 deletions ioc.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,80 @@
    #include <iostream>
    #include <typeinfo>
    #include <typeindex>
    #include <functional>
    #include <memory>
    #include <unordered_map>

    class Test
    {
    public:
    void log()
    {
    std::cout << "I'm Test! " << typeid(Test).name() << std::endl;
    }
    };

    class Test2
    {
    public:
    void log()
    {
    std::cout << "I'm Test2! " << typeid(Test).name() << std::endl;
    }
    };

    class AbstractInstance
    {
    };

    template<typename T>
    class Instance : public AbstractInstance
    {
    public:
    Instance(T *ptr) : ptr(ptr) {}
    std::shared_ptr<T> ptr;
    };

    class Container
    {
    public:
    template<typename T>
    void registerType(std::function<T * ()> callback)
    {
    m_callbacks[std::type_index(typeid(T))] = callback;
    }

    template<typename T>
    std::shared_ptr<T> make()
    {
    auto type = std::type_index(typeid(T));

    auto search = m_instances.find(type);
    if (search != m_instances.end()) {
    auto instance = std::static_pointer_cast<Instance<T>>(search->second);
    return instance->ptr;
    }

    void *ptr = m_callbacks[type]();
    auto instance = std::make_shared<Instance<T>>(static_cast<T *>(ptr));
    m_instances[type] = instance;
    return instance->ptr;
    }

    protected:
    std::unordered_map<std::type_index, std::function<void * ()>> m_callbacks;
    std::unordered_map<std::type_index, std::shared_ptr<AbstractInstance>> m_instances;
    };

    int main()
    {
    Container container;
    container.registerType<Test>([]() {
    return new Test();
    });

    auto test = container.make<Test>();
    test->log();

    return 0;
    }