#include <tuple>
#include <iostream>
#include <utility>
template <typename T>
using eval = typename T::type;
template <int i>
using int_ = std::integral_constant<int, i>;
template <typename... T>
void my_real_func(T&&... args)
{
bool foo[] = { std::cout << args << ' '... };
}
template <int ... i>
struct value_list
{
using type = value_list;
static constexpr int size = sizeof...(i);
};
template <int N, typename M = value_list<>>
struct make_value_list;
template <int N, int... i>
struct make_value_list<N, value_list<i...>>
: make_value_list<N-1, value_list<0, 1+i...>> {};
template <int... i>
struct make_value_list<0, value_list<i...>>
: value_list<i...> {};
template <int x, int y>
struct value_pair
{
friend constexpr int_<y> lookup(int_<x>, value_pair) { return {}; }
friend constexpr int_<x> reverse_lookup(int_<y>, value_pair) { return {}; }
};
template <typename T, typename U = eval<make_value_list<T::size>>>
struct value_map;
template <int... i, int... j>
struct value_map<value_list<i...>, value_list<j...>>
: value_pair<i, j>...
{};
template <int... i, typename... T, int... j>
void func_(value_list<j...>, T&&... args)
{
using tuple_type = std::tuple<T&&...>;
tuple_type arg_tuple( std::forward<T>( args )... );
using map_type = value_map<value_list<i...>>;
my_real_func( std::forward<
eval<std::tuple_element<decltype(lookup(int_<j+1>{}, map_type{}))::value, tuple_type>>>(
std::get<decltype(lookup(int_<j+1>{}, map_type{}))::value>( arg_tuple ) )... );
}
template <int... i, typename... T>
void func(T&&... args)
{
func_<i...>(eval<make_value_list<sizeof...(i)>>(), std::forward<T>( args )... );
}
int main()
{
func<5, 2, 1, 4, 3>( 10, 20, 30, 40, 50 ); std::cout << '\n';
}
I2luY2x1ZGUgPHR1cGxlPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDx1dGlsaXR5PgoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnVzaW5nIGV2YWwgPSB0eXBlbmFtZSBUOjp0eXBlOwp0ZW1wbGF0ZSA8aW50IGk+CnVzaW5nIGludF8gPSBzdGQ6OmludGVncmFsX2NvbnN0YW50PGludCwgaT47Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4gVD4Kdm9pZCBteV9yZWFsX2Z1bmMoVCYmLi4uIGFyZ3MpCnsKICAgIGJvb2wgZm9vW10gPSB7IHN0ZDo6Y291dCA8PCBhcmdzIDw8ICcgJy4uLiB9Owp9CiAKdGVtcGxhdGUgPGludCAuLi4gaT4Kc3RydWN0IHZhbHVlX2xpc3QKewogICAgdXNpbmcgdHlwZSA9IHZhbHVlX2xpc3Q7CiAgICBzdGF0aWMgY29uc3RleHByIGludCBzaXplID0gc2l6ZW9mLi4uKGkpOwp9OwoKdGVtcGxhdGUgPGludCBOLCB0eXBlbmFtZSBNID0gdmFsdWVfbGlzdDw+PgpzdHJ1Y3QgbWFrZV92YWx1ZV9saXN0Owp0ZW1wbGF0ZSA8aW50IE4sIGludC4uLiBpPgpzdHJ1Y3QgbWFrZV92YWx1ZV9saXN0PE4sICAgdmFsdWVfbGlzdDxpLi4uPj4KICAgICA6IG1ha2VfdmFsdWVfbGlzdDxOLTEsIHZhbHVlX2xpc3Q8MCwgMStpLi4uPj4ge307CnRlbXBsYXRlIDxpbnQuLi4gaT4Kc3RydWN0IG1ha2VfdmFsdWVfbGlzdDwwLCB2YWx1ZV9saXN0PGkuLi4+PgogICAgIDogdmFsdWVfbGlzdDxpLi4uPiB7fTsKCnRlbXBsYXRlIDxpbnQgeCwgaW50IHk+CnN0cnVjdCB2YWx1ZV9wYWlyCnsKICAgIGZyaWVuZCBjb25zdGV4cHIgaW50Xzx5PiBsb29rdXAoaW50Xzx4PiwgdmFsdWVfcGFpcikgeyByZXR1cm4ge307IH0KICAgIGZyaWVuZCBjb25zdGV4cHIgaW50Xzx4PiByZXZlcnNlX2xvb2t1cChpbnRfPHk+LCB2YWx1ZV9wYWlyKSB7IHJldHVybiB7fTsgfQp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFUgPSBldmFsPG1ha2VfdmFsdWVfbGlzdDxUOjpzaXplPj4+CnN0cnVjdCB2YWx1ZV9tYXA7CnRlbXBsYXRlIDxpbnQuLi4gaSwgaW50Li4uIGo+CnN0cnVjdCB2YWx1ZV9tYXA8dmFsdWVfbGlzdDxpLi4uPiwgdmFsdWVfbGlzdDxqLi4uPj4KICAgIDogdmFsdWVfcGFpcjxpLCBqPi4uLgp7fTsKCnRlbXBsYXRlIDxpbnQuLi4gaSwgdHlwZW5hbWUuLi4gVCwgaW50Li4uIGo+CnZvaWQgZnVuY18odmFsdWVfbGlzdDxqLi4uPiwgVCYmLi4uIGFyZ3MpCnsKICAgIHVzaW5nIHR1cGxlX3R5cGUgPSBzdGQ6OnR1cGxlPFQmJi4uLj47CiAgICB0dXBsZV90eXBlIGFyZ190dXBsZSggc3RkOjpmb3J3YXJkPFQ+KCBhcmdzICkuLi4gKTsKICAgIHVzaW5nIG1hcF90eXBlID0gdmFsdWVfbWFwPHZhbHVlX2xpc3Q8aS4uLj4+OwogICAgbXlfcmVhbF9mdW5jKCBzdGQ6OmZvcndhcmQ8CiAgICAgICAgIGV2YWw8c3RkOjp0dXBsZV9lbGVtZW50PGRlY2x0eXBlKGxvb2t1cChpbnRfPGorMT57fSwgbWFwX3R5cGV7fSkpOjp2YWx1ZSwgdHVwbGVfdHlwZT4+PigKICAgICAgICAgICAgIHN0ZDo6Z2V0PGRlY2x0eXBlKGxvb2t1cChpbnRfPGorMT57fSwgbWFwX3R5cGV7fSkpOjp2YWx1ZT4oIGFyZ190dXBsZSApICkuLi4gKTsKfQoKdGVtcGxhdGUgPGludC4uLiBpLCB0eXBlbmFtZS4uLiBUPgp2b2lkIGZ1bmMoVCYmLi4uIGFyZ3MpCnsKICAgIGZ1bmNfPGkuLi4+KGV2YWw8bWFrZV92YWx1ZV9saXN0PHNpemVvZi4uLihpKT4+KCksIHN0ZDo6Zm9yd2FyZDxUPiggYXJncyApLi4uICk7Cn0KCmludCBtYWluKCkKewogICAgZnVuYzw1LCAyLCAxLCA0LCAzPiggMTAsIDIwLCAzMCwgNDAsIDUwICk7IHN0ZDo6Y291dCA8PCAnXG4nOwp9