fork download
  1. #include <iostream>
  2. #include <functional>
  3. #include <type_traits>
  4. #include <utility>
  5. #include <memory>
  6. #include <cstddef>
  7. #include <mutex>
  8. #include <map>
  9.  
  10. class ABase {};
  11.  
  12. class BBase {};
  13.  
  14. class APluginInstance : public ABase {
  15.  
  16. public:
  17.  
  18. static std::shared_ptr<ABase> create(double a, double b)
  19. {
  20. return std::shared_ptr<ABase>(new APluginInstance(a,b));
  21. }
  22.  
  23. APluginInstance(double a, double b)
  24. : ret(a + b)
  25. {
  26. std::cout << ret << std::endl;
  27. }
  28.  
  29. double ret;
  30. };
  31.  
  32.  
  33. class A2PluginInstance : public ABase {
  34.  
  35. public:
  36.  
  37. static std::shared_ptr<ABase> create(double a, double b)
  38. {
  39. return std::shared_ptr<ABase>(new APluginInstance(a,b));
  40. }
  41.  
  42. A2PluginInstance(double a, double b)
  43. : ret(a - b)
  44. {
  45. std::cout << ret << std::endl;
  46. }
  47.  
  48. double ret;
  49. };
  50.  
  51. class BPluginInstance : public BBase {
  52.  
  53. public:
  54.  
  55. static std::shared_ptr<BBase> create(int a)
  56. {
  57. return std::shared_ptr<BBase>(new BPluginInstance(a));
  58. }
  59.  
  60. BPluginInstance(int a)
  61. {
  62. std::cout << a << std::endl;
  63. }
  64. };
  65.  
  66. class B2PluginInstance : public BBase {
  67.  
  68. public:
  69.  
  70. static std::shared_ptr<BBase> create(int a)
  71. {
  72. return std::shared_ptr<BBase>(new B2PluginInstance(a));
  73. }
  74.  
  75. B2PluginInstance(int a)
  76. {
  77. std::cout << -a << std::endl;
  78. }
  79. };
  80.  
  81. template <typename PluginInstanceBaseType, typename ...Args>
  82. class Plugin
  83. {
  84. public:
  85.  
  86. using PluginInstanceBase_t = PluginInstanceBaseType;
  87.  
  88.  
  89. void setFunc(const std::function<PluginInstanceBaseType(Args...)>& func)
  90. {
  91. _createFunc = func;
  92. }
  93.  
  94. PluginInstanceBaseType create(const Args&... args)
  95. {
  96. return _createFunc(args...);
  97. }
  98.  
  99. std::function<PluginInstanceBaseType(Args...)> _createFunc;
  100.  
  101. };
  102.  
  103. using APlugin = Plugin<std::shared_ptr<ABase>, double, double>;
  104. using BPlugin = Plugin<std::shared_ptr<BBase>, int>;
  105.  
  106.  
  107.  
  108. template <typename PluginType>
  109. class Factory
  110. {
  111.  
  112. public:
  113.  
  114. using PluginInstanceBase_t = typename PluginType::PluginInstanceBase_t;
  115.  
  116. template <typename T, typename...Args>
  117. void addPlugin(const std::string& name, T(*func)(Args...) )
  118. {
  119. addPlugin(name,std::function<T(Args...)>(func));
  120. }
  121.  
  122. template <typename T, typename...Args>
  123. void addPlugin(const std::string& name, const std::function<T(Args...)>& f)
  124. {
  125. std::shared_ptr<PluginType> plugin(new PluginType());
  126. plugin->setFunc(f);
  127. _plugins[name] = plugin;
  128. }
  129.  
  130. template <typename... Args>
  131. PluginInstanceBase_t create(const std::string& name, const Args&... args)
  132. {
  133. auto found = _plugins.find(name);
  134. if (found == _plugins.end()) {
  135. return PluginInstanceBase_t();
  136. }
  137. return found->second->create(args...);
  138. }
  139.  
  140. private:
  141.  
  142.  
  143. std::map<std::string, std::shared_ptr<PluginType> > _plugins;
  144. };
  145.  
  146.  
  147. using AFactory = Factory<APlugin>;
  148. using BFactory = Factory<BPlugin>;
  149.  
  150. int main()
  151. {
  152.  
  153. {
  154. // Works
  155. APlugin tmpa;
  156. tmpa.setFunc(APluginInstance::create);
  157. }
  158.  
  159. AFactory af;
  160. BFactory bf;
  161.  
  162. // Doesn't work
  163. af.addPlugin("A1", APluginInstance::create);
  164. af.addPlugin("A2", A2PluginInstance::create);
  165. bf.addPlugin("B1", BPluginInstance::create);
  166. bf.addPlugin("B2", B2PluginInstance::create);
  167.  
  168.  
  169. std::shared_ptr<ABase> a = af.create("A1",2., 4.);
  170. std::shared_ptr<ABase> a2 = af.create("A2",2., 4.);
  171. std::shared_ptr<BBase> b = bf.create("B1", 1);
  172. std::shared_ptr<BBase> b2 = bf.create("B2", 1);
  173.  
  174. return 0;
  175. }
  176.  
Success #stdin #stdout 0s 4344KB
stdin
Standard input is empty
stdout
6
6
1
-1