Files
cpp-templates/instantiator/insantiator.h
2026-02-20 21:25:09 -05:00

116 lines
3.1 KiB
C++

#ifndef INSTANTIATOR_H
#define INSTANTIATOR_H
#include <map>
#include <list>
#include <set>
#include <memory>
/**
* @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 <std::string, Base_T, int> instantiator;
* instantiator.registerType<Derived1>("one");
* instantiator.registerType<Derived2>("2");
*
* auto d1 = instantiator.create ("one")(10);
* auto d2 = instantiator.create ("2")(10);
*
* d1->get();
* d2->get();
* @endcode
*/
template<class ClassId_T, class BaseClass_T, class ... Args>
class Instantiator_T {
public:
/**
* @brief BaseClass_SP - base class shared pointer type
*/
typedef std::shared_ptr<BaseClass_T> 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<Derived1>("one");
* instantiator.registerType<Derived2>("2");
* @endcode
*/
template<class Derived>
void registerType (ClassId_T id) {
/// store pointer to constructor of Derived class
classes[id] = &instantiator<Derived>;
}
/**
* @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<ClassId_T, instantiatorFunction> 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<class Derived>
static BaseClass_SP instantiator (Args ... args) {
return std::make_shared<Derived> (args ...);
}
};
#endif // INSTANTIATOR_H