fork download
  1. #include <iostream>
  2. #include <tuple>
  3. #include <type_traits>
  4. using namespace std;
  5.  
  6. template<typename T>
  7. struct Public : public T
  8. {
  9. using unspecied_type = T;
  10. };
  11.  
  12. template<typename T>
  13. struct Private : protected T
  14. {
  15. using unspecied_type = T;
  16. };
  17.  
  18. template<typename T>
  19. struct InheritanceSpecifierAdder
  20. {
  21. using specified_type = Public<T>;
  22. };
  23.  
  24. template<typename T>
  25. struct InheritanceSpecifierAdder<Private<T>>
  26. {
  27. using specified_type = Private<T>;
  28. };
  29.  
  30. template<typename T>
  31. using AddAccessSpecifier = typename InheritanceSpecifierAdder<T>::specified_type;
  32.  
  33. template<typename... Ts>
  34. class inheriter : public AddAccessSpecifier<Ts>...
  35. {
  36. public:
  37. using ThisInheriter = inheriter<Ts...>;
  38. };
  39.  
  40. namespace impl
  41. {
  42. template<size_t, typename>
  43. struct inherited_helper;
  44.  
  45. template<size_t Index, typename... Ts>
  46. struct inherited_helper<Index, inheriter<Ts...>>
  47. {
  48. using type = typename std::tuple_element<Index, std::tuple<Ts...>>::type;
  49. };
  50. } // namespace impl
  51.  
  52. template<size_t Index, typename T>
  53. using inherited = typename impl::inherited_helper<Index, typename T::ThisInheriter>::type;
  54.  
  55. #define KMU_BASE(type) \
  56. using ThisInheriter = type;
  57.  
  58. #define THIS_TYPE \
  59. typename std::remove_reference<typename std::remove_const<decltype(*this)>::type>::type
  60.  
  61. #define INHERITED(Index) inherited<(Index), THIS_TYPE>
  62.  
  63. #define SUPER INHERITED(0)
  64. //-----------------------------------------------------------------------------
  65.  
  66. struct A
  67. {
  68. KMU_BASE(A);
  69. };
  70.  
  71. struct B : public inheriter<A>
  72. {};
  73.  
  74. struct C : public inheriter<A>
  75. {};
  76.  
  77. struct D : public inheriter<Public<B>, Public<C>>
  78. {};
  79.  
  80. struct E : public inheriter<Public<B>, Private<C>>
  81. {};
  82.  
  83. struct F;
  84.  
  85. #define DBG(X) void f(const X&) { std::cout << #X << "\n"; }
  86. DBG(A);
  87. DBG(B);
  88. DBG(C);
  89. DBG(D);
  90. DBG(E);
  91. DBG(F);
  92.  
  93. struct F : public inheriter<Private<E>>
  94. {
  95. F()
  96. {
  97. f(SUPER{});
  98. }
  99. };
  100.  
  101. //--------------------------------------------------------
  102.  
  103. int main()
  104. {
  105. f(inherited<0, D>{});
  106. f(inherited<1, D>{});
  107.  
  108. F fff;
  109. //f(inherited<0, F>{}); // error --> E private
  110.  
  111. std::cout << "\n" << sizeof(F) << "\n";
  112.  
  113. return 0;
  114. }
Success #stdin #stdout 0s 3340KB
stdin
Standard input is empty
stdout
B
C
E

2