fork download
  1. #include <type_traits>
  2.  
  3. template<typename... Types>
  4. struct TypeList {};
  5.  
  6. template<typename T, typename List, typename=void>
  7. struct IndexOf;
  8.  
  9. template<typename T, typename First, typename... Types>
  10. struct IndexOf<T, TypeList<First, Types...>,
  11. typename std::enable_if<
  12. std::is_same< T, First >::value
  13. >::type
  14. > {
  15. enum {value = 0};
  16. };
  17.  
  18. template<typename T, typename First, typename... Types>
  19. struct IndexOf<T, TypeList<First, Types...>,
  20. typename std::enable_if<
  21. !std::is_same< T, First >::value
  22. >::type
  23. > {
  24. enum {value = 1+IndexOf<T, TypeList<Types...>>::value};
  25. };
  26.  
  27. template<size_t n, typename List>
  28. struct TypeAt;
  29.  
  30. template<size_t n, typename First, typename... Types>
  31. struct TypeAt<n, TypeList<First, Types...>> {
  32. typedef typename TypeAt<n-1, TypeList<Types...>>::type type;
  33. };
  34.  
  35. template<typename First, typename... Types>
  36. struct TypeAt<0, TypeList<First, Types...>> {
  37. typedef First type;
  38. };
  39.  
  40. template<typename Functor, typename List>
  41. struct TypeDispatch {
  42. struct Helper {
  43. Helper( Functor f_ ):f(f_) {}
  44. Functor f;
  45. template<size_t n>
  46. void Call() {
  47. typedef typename TypeAt<n, List>::type target_type;
  48. f.template Call<target_type>();
  49. }
  50. };
  51. };
  52.  
  53. template<size_t max>
  54. struct RuntimeSwitch {
  55. template<typename Functor>
  56. static bool Call( size_t n, Functor f ) {
  57. if (n == max) {
  58. f.template Call<max>();
  59. return true;
  60. } else {
  61. return RuntimeSwitch<max-1>::template Call( n, f );
  62. }
  63. }
  64. };
  65.  
  66. template<>
  67. struct RuntimeSwitch< size_t(-1) > {
  68. template<typename Functor>
  69. static bool Call( size_t n, Functor f ) {
  70. return false;
  71. }
  72. };
  73.  
  74. template<typename List>
  75. struct DynamicTypeDispatch;
  76.  
  77. template<typename... Types>
  78. struct DynamicTypeDispatch<TypeList<Types...>> {
  79. template<typename Functor>
  80. static bool Call( size_t n, Functor f ) {
  81. typedef TypeDispatch<Functor, TypeList<Types...>> typeDispatch;
  82. typedef typename typeDispatch::Helper typeCaller;
  83. return RuntimeSwitch<sizeof...(Types)-1>::Call(n, typeCaller(f));
  84. }
  85. };
  86.  
  87. #include <iostream>
  88. #include <string>
  89. struct Test {
  90. std::string s;
  91. Test( std::string s_ ):s(s_) {}
  92. template<typename T>
  93. void Call() {
  94. std::cout << sizeof(T) << " == " << s.c_str() << " I hope\n";
  95. }
  96. };
  97. int main()
  98. {
  99. typedef TypeList<int, double> TestList;
  100. DynamicTypeDispatch<TestList>::Call( 0, Test("4") );
  101. DynamicTypeDispatch<TestList>::Call( 1, Test("8") );
  102. }
  103.  
  104.  
Success #stdin #stdout 0s 3064KB
stdin
Standard input is empty
stdout
4 == 4 I hope
8 == 8 I hope