#ifndef INSTANTIATOR_H #define INSTANTIATOR_H #include #include #include #include /** * @brief The Instantiator_T class - base instantiator (abstract factory) template * @param ClassId_T - unique class identification class. For example string, or integer id. * @param BaseClass_T - all objects should have one base class. For example vehicle or parameter * @param Args - constructor arguments * * Usage example: * @code * class Base_T { * public: * virtual int get() = 0; * } * * class Derived1_T : public Base_T { * public: * Derived1_T (int start) : m_start(start){} * int get() override { * return m_start + 1; * } * private: * int m_start = 0; * } * * class Derived2_T : public Base_T { * public: * Derived1_T (int start) : m_start(start){} * int get() override { * return m_start + 2; * } * private: * int m_start = 0; * } * . * . * . * Instantiator_T instantiator; * instantiator.registerType("one"); * instantiator.registerType("2"); * * auto d1 = instantiator.create ("one")(10); * auto d2 = instantiator.create ("2")(10); * * d1->get(); * d2->get(); * @endcode */ template class Instantiator_T { public: /** * @brief BaseClass_SP - base class shared pointer type */ typedef std::shared_ptr BaseClass_SP; /** * @brief instantiatorFunction - instantiator function pointer type. Generally speaking it is pointer to constructor. */ typedef BaseClass_SP (*instantiatorFunction) (Args ...); Instantiator_T() = default; /** * @brief registerType - template function to register class in factory * @param Derived - registering type * @param id - unique class identification * * Usage example: * @code * instantiator.registerType("one"); * instantiator.registerType("2"); * @endcode */ template void registerType (ClassId_T id) { /// store pointer to constructor of Derived class classes[id] = &instantiator; } /** * @brief create - create class by unique id. Class should be registered before * @param id - unique class identification * @return shared pointer to new class. * @throws std::our_of_range when id not found in map */ instantiatorFunction create (ClassId_T id) const { /// constructor of registered type will call here return classes.at (id); } protected: /** * @brief classes - main storage for pointers to constructors of registered types */ std::map classes; private: /** * @brief instantiator - main functionality, create registered object * @param Derived - class type * @param args - constructor arguments * @return shared pointer to register Derived class */ template static BaseClass_SP instantiator (Args ... args) { return std::make_shared (args ...); } }; #endif // INSTANTIATOR_H