fork download
  1. #include <iostream>
  2. #include <type_traits>
  3. #include <typeinfo>
  4.  
  5. using namespace std;
  6.  
  7. template<typename ParserTraits>
  8. struct ModuleA {
  9.  
  10.  
  11. using ParserType = typename ParserTraits::ParserType;
  12. using DType = typename ParserTraits::DType;
  13. using OptionsType = int;
  14.  
  15. using ModuleBType = typename ParserTraits::ModuleBType;
  16. using ModuleBOptions = typename ModuleBType::OptionsType;
  17.  
  18. void foo(){
  19. std::cout << "ModuleA::foo: ParserType: " << typeid(ParserType).name() << std::endl;
  20. std::cout << "ModuleA::foo: ModuleBType: " << typeid(ModuleBType).name() << std::endl;
  21. std::cout << "ModuleA::foo: ModuleBOptions: " << typeid(ModuleBOptions).name() << std::endl;
  22. }
  23. };
  24.  
  25. template<typename ParserTraits>
  26. struct ModuleB {
  27. using ParserType = typename ParserTraits::ParserType;
  28. using DType = typename ParserTraits::DType;
  29. using OptionsType = float;
  30.  
  31. using ModuleAType = typename ParserTraits::ModuleAType;
  32. using ModuleAOptions = typename ModuleAType::OptionsType; //uncomment this!!
  33.  
  34. void foo(){
  35. std::cout << "ModuleB::foo: ParserType: " << typeid(ParserType).name() << std::endl;
  36. std::cout << "ModuleB::foo: ModuleAType: " << typeid(ModuleAType).name() << std::endl;
  37. std::cout << "ModuleB::foo: ModuleAOptions: " << typeid(ModuleAOptions).name() << std::endl;
  38. }
  39. };
  40.  
  41. // The PARSER TYPE TRAITS Struct!!
  42. template<typename Parser,typename D>
  43. struct ParserTraits {
  44. using DType = D;
  45. using ParserType = Parser;
  46.  
  47. using ModuleAType = ModuleA<ParserTraits>;
  48. using ModuleBType = ModuleB<ParserTraits>;
  49. };
  50.  
  51. template<typename D, typename Derived = void >
  52. struct Parser {
  53.  
  54. using DType = D;
  55.  
  56. // Inject the derived class as the parser class for the modules
  57. using DerivedType = typename std::conditional< std::is_same<Derived,void>::value, Parser, Derived>::type;
  58. using ParserTraitsType = ParserTraits<DerivedType,DType>;
  59.  
  60. using ModuleAType = ModuleA<ParserTraitsType>;
  61. using ModuleBType = ModuleB<ParserTraitsType>;
  62.  
  63. using ModuleAOptions = typename ModuleAType::OptionsType; //uncomment this!!
  64. using ModuleBOptions = typename ModuleBType::OptionsType; //uncomment this!!
  65.  
  66. virtual void foo(){
  67. std::cout << "Parser::foo" << std::endl;
  68. ModuleAType a;
  69. a.foo();
  70. ModuleBType b;
  71. b.foo();
  72. }
  73. };
  74.  
  75. template<typename D>
  76. struct ParserGUI: Parser<D, ParserGUI<D> > {
  77.  
  78. using Base = Parser<D, ParserGUI<D> >;
  79.  
  80. void foo(){
  81. std::cout << "ParserGUI::foo" << std::endl;
  82. typename Base::ModuleAType a;
  83. a.foo();
  84. typename Base::ModuleBType b;
  85. b.foo();
  86. }
  87.  
  88. };
  89.  
  90. int test() {
  91. std::cout << "SceneParser1" << std::endl;
  92. Parser<double> t;
  93. t.foo();
  94.  
  95. ParserGUI<double> d;
  96. d.foo();
  97.  
  98. ParserGUI<double> r;
  99. ParserGUI<double>::Base & base = r;
  100. base.foo();
  101. }
  102.  
  103.  
  104. int main(){
  105. test();
  106. }
  107.  
Success #stdin #stdout 0s 3304KB
stdin
Standard input is empty
stdout
SceneParser1
Parser::foo
ModuleA::foo: ParserType: 6ParserIdvE
ModuleA::foo: ModuleBType: 7ModuleBI12ParserTraitsI6ParserIdvEdEE
ModuleA::foo: ModuleBOptions: f
ModuleB::foo: ParserType: 6ParserIdvE
ModuleB::foo: ModuleAType: 7ModuleAI12ParserTraitsI6ParserIdvEdEE
ModuleB::foo: ModuleAOptions: i
ParserGUI::foo
ModuleA::foo: ParserType: 9ParserGUIIdE
ModuleA::foo: ModuleBType: 7ModuleBI12ParserTraitsI9ParserGUIIdEdEE
ModuleA::foo: ModuleBOptions: f
ModuleB::foo: ParserType: 9ParserGUIIdE
ModuleB::foo: ModuleAType: 7ModuleAI12ParserTraitsI9ParserGUIIdEdEE
ModuleB::foo: ModuleAOptions: i
ParserGUI::foo
ModuleA::foo: ParserType: 9ParserGUIIdE
ModuleA::foo: ModuleBType: 7ModuleBI12ParserTraitsI9ParserGUIIdEdEE
ModuleA::foo: ModuleBOptions: f
ModuleB::foo: ParserType: 9ParserGUIIdE
ModuleB::foo: ModuleAType: 7ModuleAI12ParserTraitsI9ParserGUIIdEdEE
ModuleB::foo: ModuleAOptions: i