diff --git a/instantiator/insantiator.h b/instantiator/insantiator.h new file mode 100644 index 0000000..fc4c093 --- /dev/null +++ b/instantiator/insantiator.h @@ -0,0 +1,115 @@ +#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