#include <tuple>
#include <iostream>

namespace details
{
    template<typename Int, typename, Int Begin, bool Increasing>
    struct integer_range_impl;

    template<typename Int, Int... N, Int Begin>
    struct integer_range_impl<Int, std::integer_sequence<Int, N...>, Begin, true> {
        using type = std::integer_sequence<Int, N+Begin...>;
    };

    template<typename Int, Int... N, Int Begin>
    struct integer_range_impl<Int, std::integer_sequence<Int, N...>, Begin, false> {
        using type = std::integer_sequence<Int, Begin-N...>;
    };
}

template<typename Int, Int Begin, Int End>
using integer_range = typename details::integer_range_impl<
    Int,
    std::make_integer_sequence<Int, (Begin<End) ? End-Begin : Begin-End>,
    Begin,
    (Begin<End) >::type;

template<std::size_t Begin, std::size_t End>
using index_range = integer_range<std::size_t, Begin, End>;

template<size_t N, class Tuple, class Func>
void tuple_call_assign(Tuple&& source, Tuple&& target, Func f)
{
    std::get<N>(std::forward<Tuple>(target)) = f(std::get<N>(std::forward<Tuple>(source)));	
}

template<size_t From, size_t To, class Tuple, class Func, size_t...Is>
void tuple_transform(Tuple&& source, Tuple&& target, Func f, std::index_sequence<Is...>)
{
    using expander = int[];
    (void)expander { 0, ((void)tuple_call_assign<Is>(source,target,f), 0)... };
}

template<size_t From, size_t To, class Tuple, class Func>
void tuple_transform(Tuple&& source, Tuple&& target, Func f)
{
    tuple_transform<From,To>(std::forward<Tuple>(source), std::forward<Tuple>(target), f,
                    index_range<From,To>());
}


int main()
{
	std::tuple<int,int,int> a = std::make_tuple(1,2,3);
	std::tuple<int,int,int> b;
	tuple_transform<0,3>(a,b,[](int a){return a*2;});
	std::cout << std::get<0>(b);
	std::cout << std::get<1>(b);
	std::cout << std::get<2>(b);
}