79 lines
2 KiB
C++
79 lines
2 KiB
C++
#ifndef BE13A370_B199_43EC_A4E6_E2D4FD197D63
|
|
#define BE13A370_B199_43EC_A4E6_E2D4FD197D63
|
|
/*
|
|
*******************************************************************************
|
|
* INCLUDE
|
|
*******************************************************************************
|
|
*/
|
|
#include "ClassAssistant.h"
|
|
#include <map>
|
|
#include <Poco/SharedPtr.h>
|
|
#include <Poco/Format.h>
|
|
|
|
namespace Util
|
|
{
|
|
/*
|
|
*******************************************************************************
|
|
* CLASS DECLARE
|
|
*******************************************************************************
|
|
*/
|
|
template <class T> class SimpleSelector
|
|
{
|
|
public:
|
|
static T select(T val)
|
|
{
|
|
return val;
|
|
}
|
|
};
|
|
|
|
template <class T, class TKey, class TSelector, class... TArgs> class FactoryManager
|
|
{
|
|
private:
|
|
class IFactory
|
|
{
|
|
public:
|
|
using Ptr = Poco::SharedPtr<IFactory>;
|
|
virtual ~IFactory()
|
|
{
|
|
}
|
|
|
|
public:
|
|
virtual T* create(TArgs... args) = 0;
|
|
};
|
|
|
|
template <class C> class Factory: public IFactory
|
|
{
|
|
public:
|
|
C* create(TArgs... args) override
|
|
{
|
|
return new C(args...);
|
|
}
|
|
};
|
|
|
|
using Factories = std::map<TKey, typename IFactory::Ptr>;
|
|
|
|
public:
|
|
static T* create(TArgs... args)
|
|
{
|
|
TKey key = TSelector::select(args...);
|
|
if (_factories.find(key) == _factories.end())
|
|
throw Poco::NotFoundException(
|
|
Poco::format("FactoryManager: Factory '%s' does not exists.", Util::ClassAssistant::demangle<T>()),
|
|
-EINVAL);
|
|
|
|
return _factories[key]->create(args...);
|
|
}
|
|
|
|
template <class C> static void registerClass(TKey key)
|
|
{
|
|
_factories[key] = new Factory<C>();
|
|
}
|
|
|
|
private:
|
|
static Factories _factories;
|
|
};
|
|
|
|
template <class T, class TKey, class TSelect, class... TArgs>
|
|
typename FactoryManager<T, TKey, TSelect, TArgs...>::Factories FactoryManager<T, TKey, TSelect, TArgs...>::_factories;
|
|
}
|
|
#endif
|