#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 SN, size_t DN, class TSrc, class TDest, class Func>
void tuple_call_assign(TSrc&& source, TDest& target, Func f)
{
std::get<DN>(target) = f(std::get<SN>(std::forward<TSrc>(source)));
}
template<size_t From, size_t To, class TSrc, class TDest, class Func, size_t...Is, size_t...DIs>
void tuple_transform(TSrc&& source, TDest& target, Func f,
std::index_sequence<Is...>, std::index_sequence<DIs...>)
{
using expander = int[];
(void)expander { 0, (tuple_call_assign<Is,DIs>(std::forward<TSrc>(source),target,f), 0)... };
}
template<size_t From, size_t To, size_t FromDest, class TSrc, class TDest, class Func>
void tuple_transform(TSrc&& source, TDest& target, Func f)
{
static_assert(To > From, "Range must be increasing");
static_assert(To <= std::tuple_size<std::decay_t<TSrc>>::value+1,
"Range must be valid for source tuple");
constexpr size_t RangeSize = To-From;
static_assert(FromDest+RangeSize <= std::tuple_size<std::decay_t<TDest>>::value,
"Range must be valid for target tuple");
tuple_transform<From,To>(std::forward<TSrc>(source), target, f,
index_range<From,To>(), index_range<FromDest, FromDest+RangeSize>());
}
int main()
{
std::tuple<int,int,int> a = std::make_tuple(1,2,3);
std::tuple<int,int,int> b;
tuple_transform<0,2,1>(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);
}
I2luY2x1ZGUgPHR1cGxlPgojaW5jbHVkZSA8aW9zdHJlYW0+CgpuYW1lc3BhY2UgZGV0YWlscwp7CiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBJbnQsIHR5cGVuYW1lLCBJbnQgQmVnaW4sIGJvb2wgSW5jcmVhc2luZz4KICAgIHN0cnVjdCBpbnRlZ2VyX3JhbmdlX2ltcGw7CgogICAgdGVtcGxhdGU8dHlwZW5hbWUgSW50LCBJbnQuLi4gTiwgSW50IEJlZ2luPgogICAgc3RydWN0IGludGVnZXJfcmFuZ2VfaW1wbDxJbnQsIHN0ZDo6aW50ZWdlcl9zZXF1ZW5jZTxJbnQsIE4uLi4+LCBCZWdpbiwgdHJ1ZT4gewogICAgICAgIHVzaW5nIHR5cGUgPSBzdGQ6OmludGVnZXJfc2VxdWVuY2U8SW50LCBOK0JlZ2luLi4uPjsKICAgIH07CgogICAgdGVtcGxhdGU8dHlwZW5hbWUgSW50LCBJbnQuLi4gTiwgSW50IEJlZ2luPgogICAgc3RydWN0IGludGVnZXJfcmFuZ2VfaW1wbDxJbnQsIHN0ZDo6aW50ZWdlcl9zZXF1ZW5jZTxJbnQsIE4uLi4+LCBCZWdpbiwgZmFsc2U+IHsKICAgICAgICB1c2luZyB0eXBlID0gc3RkOjppbnRlZ2VyX3NlcXVlbmNlPEludCwgQmVnaW4tTi4uLj47CiAgICB9Owp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBJbnQsIEludCBCZWdpbiwgSW50IEVuZD4KdXNpbmcgaW50ZWdlcl9yYW5nZSA9IHR5cGVuYW1lIGRldGFpbHM6OmludGVnZXJfcmFuZ2VfaW1wbDwKICAgIEludCwKICAgIHN0ZDo6bWFrZV9pbnRlZ2VyX3NlcXVlbmNlPEludCwgKEJlZ2luPEVuZCkgPyBFbmQtQmVnaW4gOiBCZWdpbi1FbmQ+LAogICAgQmVnaW4sCiAgICAoQmVnaW48RW5kKSA+Ojp0eXBlOwoKdGVtcGxhdGU8c3RkOjpzaXplX3QgQmVnaW4sIHN0ZDo6c2l6ZV90IEVuZD4KdXNpbmcgaW5kZXhfcmFuZ2UgPSBpbnRlZ2VyX3JhbmdlPHN0ZDo6c2l6ZV90LCBCZWdpbiwgRW5kPjsKCnRlbXBsYXRlPHNpemVfdCBTTiwgc2l6ZV90IEROLCBjbGFzcyBUU3JjLCBjbGFzcyBURGVzdCwgY2xhc3MgRnVuYz4Kdm9pZCB0dXBsZV9jYWxsX2Fzc2lnbihUU3JjJiYgc291cmNlLCBURGVzdCYgdGFyZ2V0LCBGdW5jIGYpCnsKICAgIHN0ZDo6Z2V0PEROPih0YXJnZXQpID0gZihzdGQ6OmdldDxTTj4oc3RkOjpmb3J3YXJkPFRTcmM+KHNvdXJjZSkpKTsJCn0KCnRlbXBsYXRlPHNpemVfdCBGcm9tLCBzaXplX3QgVG8sIGNsYXNzIFRTcmMsIGNsYXNzIFREZXN0LCBjbGFzcyBGdW5jLCBzaXplX3QuLi5Jcywgc2l6ZV90Li4uRElzPgp2b2lkIHR1cGxlX3RyYW5zZm9ybShUU3JjJiYgc291cmNlLCBURGVzdCYgdGFyZ2V0LCBGdW5jIGYsCiAgICAgICAgICAgICAgICAgICAgIHN0ZDo6aW5kZXhfc2VxdWVuY2U8SXMuLi4+LCBzdGQ6OmluZGV4X3NlcXVlbmNlPERJcy4uLj4pCnsKICAgIHVzaW5nIGV4cGFuZGVyID0gaW50W107CiAgICAodm9pZClleHBhbmRlciB7IDAsICh0dXBsZV9jYWxsX2Fzc2lnbjxJcyxESXM+KHN0ZDo6Zm9yd2FyZDxUU3JjPihzb3VyY2UpLHRhcmdldCxmKSwgMCkuLi4gfTsKfQoKdGVtcGxhdGU8c2l6ZV90IEZyb20sIHNpemVfdCBUbywgc2l6ZV90IEZyb21EZXN0LCBjbGFzcyBUU3JjLCBjbGFzcyBURGVzdCwgY2xhc3MgRnVuYz4Kdm9pZCB0dXBsZV90cmFuc2Zvcm0oVFNyYyYmIHNvdXJjZSwgVERlc3QmIHRhcmdldCwgRnVuYyBmKQp7CglzdGF0aWNfYXNzZXJ0KFRvID4gRnJvbSwgIlJhbmdlIG11c3QgYmUgaW5jcmVhc2luZyIpOwoJc3RhdGljX2Fzc2VydChUbyA8PSBzdGQ6OnR1cGxlX3NpemU8c3RkOjpkZWNheV90PFRTcmM+Pjo6dmFsdWUrMSwgCgkgICAgICJSYW5nZSBtdXN0IGJlIHZhbGlkIGZvciBzb3VyY2UgdHVwbGUiKTsKCWNvbnN0ZXhwciBzaXplX3QgUmFuZ2VTaXplID0gVG8tRnJvbTsKCXN0YXRpY19hc3NlcnQoRnJvbURlc3QrUmFuZ2VTaXplIDw9IHN0ZDo6dHVwbGVfc2l6ZTxzdGQ6OmRlY2F5X3Q8VERlc3Q+Pjo6dmFsdWUsIAoJICAgICAiUmFuZ2UgbXVzdCBiZSB2YWxpZCBmb3IgdGFyZ2V0IHR1cGxlIik7CgkKICAgIHR1cGxlX3RyYW5zZm9ybTxGcm9tLFRvPihzdGQ6OmZvcndhcmQ8VFNyYz4oc291cmNlKSwgdGFyZ2V0LCBmLAogICAgICAgICAgICAgICAgICAgIGluZGV4X3JhbmdlPEZyb20sVG8+KCksIGluZGV4X3JhbmdlPEZyb21EZXN0LCBGcm9tRGVzdCtSYW5nZVNpemU+KCkpOwp9CgoKaW50IG1haW4oKQp7CglzdGQ6OnR1cGxlPGludCxpbnQsaW50PiBhID0gc3RkOjptYWtlX3R1cGxlKDEsMiwzKTsKCXN0ZDo6dHVwbGU8aW50LGludCxpbnQ+IGI7Cgl0dXBsZV90cmFuc2Zvcm08MCwyLDE+KGEsYixbXShpbnQgYSl7cmV0dXJuIGEqMjt9KTsKCXN0ZDo6Y291dCA8PCBzdGQ6OmdldDwwPihiKTsKCXN0ZDo6Y291dCA8PCBzdGQ6OmdldDwxPihiKTsKCXN0ZDo6Y291dCA8PCBzdGQ6OmdldDwyPihiKTsKfQ==