fork download
  1. #include <iostream>
  2. #include <stdexcept>
  3.  
  4. template<typename Base, typename Class, typename... Classes>
  5. struct Factory
  6. {
  7. private:
  8. // creator proc
  9. template<typename T>
  10. static constexpr typename std::enable_if<std::is_base_of<Base,T>::value,Base>::type*
  11. create()
  12. {
  13. return new T();
  14. }
  15.  
  16. // creator table
  17. static Base* (*pfns[])();
  18.  
  19. public:
  20. // return instance if in-range
  21. Base* get(std::size_t i)
  22. {
  23. if (i > sizeof...(Classes))
  24. throw std::out_of_range("Invalid class index");
  25. return pfns[i]();
  26. }
  27.  
  28. // return number of supported derivations
  29. static constexpr std::size_t size()
  30. {
  31. return sizeof...(Classes)+1;
  32. }
  33. };
  34.  
  35. // static creator table
  36. template<typename Base, typename Class, typename... Classes>
  37. Base* (*Factory<Base,Class,Classes...>::pfns[])() =
  38. {
  39. Factory<Base, Class, Classes...>::template create<Class>,
  40. Factory<Base, Class, Classes...>::template create<Classes>...
  41. };
  42. ////////////////////////////////////////////////////////////////////////////////
  43.  
  44.  
  45. class Base
  46. {
  47. public:
  48. virtual ~Base()
  49. {
  50. std::cout << __PRETTY_FUNCTION__ << std::endl;
  51. }
  52. };
  53.  
  54. class DeriveOne : public Base
  55. {
  56. public:
  57. DeriveOne()
  58. {
  59. std::cout << __PRETTY_FUNCTION__ << std::endl;
  60. }
  61. };
  62.  
  63. class DeriveTwo : public Base
  64. {
  65. public:
  66. DeriveTwo()
  67. {
  68. std::cout << __PRETTY_FUNCTION__ << std::endl;
  69. }
  70. };
  71.  
  72. class DeriveThree : public DeriveTwo
  73. {
  74. public:
  75. DeriveThree()
  76. {
  77. std::cout << __PRETTY_FUNCTION__ << std::endl;
  78. }
  79. };
  80. ////////////////////////////////////////////////////////////////////////////////
  81.  
  82.  
  83. int main(int argc, char *argv[])
  84. {
  85. Factory<Base, DeriveOne, DeriveTwo, DeriveThree> f1;
  86.  
  87. for (std::size_t i=0; i<f1.size(); ++i)
  88. {
  89. Base *p = f1.get(i);
  90. delete p;
  91. }
  92.  
  93. return EXIT_SUCCESS;
  94. }
Success #stdin #stdout 0s 3432KB
stdin
Standard input is empty
stdout
DeriveOne::DeriveOne()
virtual Base::~Base()
DeriveTwo::DeriveTwo()
virtual Base::~Base()
DeriveTwo::DeriveTwo()
DeriveThree::DeriveThree()
virtual Base::~Base()