fork download
  1. #include <tuple>
  2. #include <iostream>
  3. #include <utility>
  4.  
  5. template <typename T>
  6. using eval = typename T::type;
  7. template <int i>
  8. using int_ = std::integral_constant<int, i>;
  9.  
  10. template <typename... T>
  11. void my_real_func(T&&... args)
  12. {
  13. bool foo[] = { std::cout << args << ' '... };
  14. }
  15.  
  16. template <int ... i>
  17. struct value_list
  18. {
  19. using type = value_list;
  20. static constexpr int size = sizeof...(i);
  21. };
  22.  
  23. template <int N, typename M = value_list<>>
  24. struct make_value_list;
  25. template <int N, int... i>
  26. struct make_value_list<N, value_list<i...>>
  27. : make_value_list<N-1, value_list<0, 1+i...>> {};
  28. template <int... i>
  29. struct make_value_list<0, value_list<i...>>
  30. : value_list<i...> {};
  31.  
  32. template <int x, int y>
  33. struct value_pair
  34. {
  35. friend constexpr int_<y> lookup(int_<x>, value_pair) { return {}; }
  36. friend constexpr int_<x> reverse_lookup(int_<y>, value_pair) { return {}; }
  37. };
  38.  
  39. template <typename T, typename U = eval<make_value_list<T::size>>>
  40. struct value_map;
  41. template <int... i, int... j>
  42. struct value_map<value_list<i...>, value_list<j...>>
  43. : value_pair<i, j>...
  44. {};
  45.  
  46. template <int... i, typename... T, int... j>
  47. void func_(value_list<j...>, T&&... args)
  48. {
  49. using tuple_type = std::tuple<T&&...>;
  50. tuple_type arg_tuple( std::forward<T>( args )... );
  51. using map_type = value_map<value_list<i...>>;
  52. my_real_func( std::forward<
  53. eval<std::tuple_element<decltype(lookup(int_<j+1>{}, map_type{}))::value, tuple_type>>>(
  54. std::get<decltype(lookup(int_<j+1>{}, map_type{}))::value>( arg_tuple ) )... );
  55. }
  56.  
  57. template <int... i, typename... T>
  58. void func(T&&... args)
  59. {
  60. func_<i...>(eval<make_value_list<sizeof...(i)>>(), std::forward<T>( args )... );
  61. }
  62.  
  63. int main()
  64. {
  65. func<5, 2, 1, 4, 3>( 10, 20, 30, 40, 50 ); std::cout << '\n';
  66. }
Success #stdin #stdout 0s 3296KB
stdin
Standard input is empty
stdout
30 20 50 40 10