fork download
  1. #include <typeindex>
  2. #include <unordered_map>
  3.  
  4. struct PBase {virtual ~PBase() noexcept = default;};
  5. struct P1 : public PBase {};
  6. struct P2 : public PBase {};
  7.  
  8. class SBase
  9. {
  10. public:
  11. void doIt(PBase *base)
  12. {
  13. internalDoIt(base);
  14. }
  15.  
  16. protected:
  17. virtual void internalDoIt(PBase *base) = 0;
  18. };
  19.  
  20. using callback_type = void(*)(SBase*, PBase*);
  21. using map_type = std::unordered_map<std::type_index, callback_type>;
  22.  
  23. template <typename P, callback_type Fnc>
  24. struct pair_type {};
  25.  
  26. template <class ... Pairs>
  27. class BasicS : public SBase
  28. {
  29. protected:
  30. void internalDoIt(PBase *base) override
  31. {
  32. map_[typeid(*base)](this, base);
  33. }
  34.  
  35. private:
  36. static map_type map_;
  37. };
  38.  
  39. namespace detail
  40. {
  41. template <class ... Pairs>
  42. struct map_getter;
  43.  
  44. template <typename P, callback_type F>
  45. struct map_getter<pair_type<P, F>>
  46. {
  47. static map_type get()
  48. {
  49. return map_type{{typeid(P), F}};
  50. }
  51. };
  52.  
  53. template <typename P, callback_type F, class ... Tail>
  54. struct map_getter<pair_type<P, F>, Tail...>
  55. {
  56. static map_type get()
  57. {
  58. auto m = map_getter<Tail...>::get();
  59. m.emplace(typeid(P), F);
  60. return m;
  61. }
  62. };
  63. }
  64.  
  65. template <class ... Pairs>
  66. map_type BasicS<Pairs...>::map_ = detail::map_getter<Pairs...>::get();
  67.  
  68. #include <iostream>
  69.  
  70. void s1p1DoIt(SBase*, PBase*)
  71. {
  72. std::cout << "S1 P1\n";
  73. }
  74.  
  75. void s1p2DoIt(SBase*, PBase*)
  76. {
  77. std::cout << "S1 P2\n";
  78. }
  79.  
  80. class S1 : public BasicS<pair_type<P1, s1p1DoIt>, pair_type<P2, s1p2DoIt>> {};
  81.  
  82. void s2p1DoIt(SBase*, PBase*)
  83. {
  84. std::cout << "S2 P1\n";
  85. }
  86.  
  87. void s2p2DoIt(SBase*, PBase*)
  88. {
  89. std::cout << "S2 P2\n";
  90. }
  91.  
  92. class S2 : public BasicS<pair_type<P1, s2p1DoIt>, pair_type<P2, s2p2DoIt>> {};
  93.  
  94. int main()
  95. {
  96. S1 s1;
  97. S2 s2;
  98. P1 p1;
  99. P2 p2;
  100.  
  101. SBase &sbase1 = s1;
  102. SBase &sbase2 = s2;
  103. PBase &pbase1 = p1;
  104. PBase &pbase2 = p2;
  105.  
  106. sbase1.doIt(&pbase1);
  107. sbase1.doIt(&pbase2);
  108. sbase2.doIt(&pbase1);
  109. sbase2.doIt(&pbase2);
  110. }
  111.  
Success #stdin #stdout 0s 3476KB
stdin
Standard input is empty
stdout
S1 P1
S1 P2
S2 P1
S2 P2